>백엔드 개발 >PHP 튜토리얼 >PHP 조합 모드에 대한 자세한 설명 및 사례

PHP 조합 모드에 대한 자세한 설명 및 사례

墨辰丷
墨辰丷원래의
2018-05-16 14:29:171582검색

이 글은 주로 PHP 조합 모드에 대한 자세한 설명과 사례를 소개하고 있으니 관심 있는 분들이 참고하시면 좋을 것 같습니다.

이 모델은 이해하기 다소 모호할 수 있으며, 특히 일부 책의 어려운 설명은 더욱 그렇습니다. 먼저 조합 모델의 몇 가지 특징에 대해 이야기해 보겠습니다.

1. 분리할 수 없는 기본 요소가 있어야 합니다.

2. 결합된 개체는 결합될 수 있습니다.

일반적인 예를 들자면 원자는 화학 반응의 기본 입자이며 화학 반응에서 분리될 수 없습니다. 이제 C(탄소), H(수소), O(산소), N(질소)의 네 가지 유형의 원자가 무작위로 결합되어 단백질이든 지방이든 무수한 분자가 될 수 있습니다. 단백질과 지방은 고기, 콩 등에 결합될 수 있습니다.

주제로 돌아가서 이제 요구 사항이 있습니다. 고객이 리프를 생성해야 하며 리프 크기와 색상을 설정할 수 있고 리프에 이름을 지정할 수 있습니다.

abstract class tree{  
    abstract function create();  
}  
class createLeaf extends tree{  
      
    private $name;  
    private $size;  
    private $color;  
    private $leaf=array();  
      
    public function __construct($name,$size,$color){  
        $this->name=$name;  
        $this->size=$size;  
        $this->color=$color;  
    }  
      
    public function create(){  
        $this->leaf[$this->name]=array(  
            'size'=>$this->size,  
            'color'=>$this->color  
        );  
        return $this->leaf;  
    }  
      
}  
  
$leaf=new createLeaf('大红树叶','大','红');  
  
print_r($leaf->create());  
  
运行以上代码将得到:  
  
  
Array  
(  
    [大红树叶] => Array  
        (  
            [size] => 大  
            [color] => 红  
        )  
  
)

저희 디자인은 고객의 요구를 완벽하게 충족시켰지만 이제 고객의 새로운 요구 사항이 다가오고 있습니다. 나뭇잎을 만들 수 있을 뿐만 아니라 가지를 만들 수도 있고, 가지에 나뭇잎을 놓을 수도 있습니다. 좋은 잎은 가지에서 제거됩니다. 그들이 궁극적으로 원하는 것은 가지에 다른 가지를 배치하여 잎이 많은 나무를 만들 수 있다는 것입니다


분석: 나뭇잎을 만드는 것과 가지를 만드는 것은 모두 생성 작업을 가지므로 둘 다 추상화할 수 있습니다. 트리 클래스가 구현되지만 클래스는 브랜치를 생성하는 메서드도 설치하고 제거해야 하므로 당분간 트리 클래스에 두 개의 추상 메서드인 Combination()과 Separation()을 추가합니다.

abstract class tree{  
    abstract function create();//创建  
    abstract function combination(tree $item);//组合  
    abstract function separation(tree $item);//分离  
}  
  
class createLeaf extends tree{  
      
    private $name;  
    private $size;  
    private $color;  
    private $leaf=array();  
      
    public function __construct($name,$size,$color){  
        $this->name=$name;  
        $this->size=$size;  
        $this->color=$color;  
    }  
      
    public function create(){  
        $this->leaf[$this->name]=array(  
            'size'=>$this->size,  
            'color'=>$this->color  
        );  
        return $this->leaf;  
    }  
  
    //由于创建叶子类不需要组合和分离的操作,我们将这两个方法投掷出错误警告。      
    public function combination(tree $item){  
        throw new Exception("本类不支持组合操作");  
    }  
      
    public function separation(tree $item){  
        throw new Exception("本类不支持分离操作");  
    }  
      
}  
  
class createBranch extends tree{  
  
    private $name;  
    private $branch=array();  
    private $items=array();//树枝可能被安插叶子,该变量用于存放叶子对象  
      
    public function __construct($name){  
        $this->name=$name;  
    }  
      
    //我们已经知道$items内的对象都包含创建操作,所以只要依次执行各对象的创建操作,收集结果便可  
    public function create(){  
        foreach($this->items as $item){  
            $arr=$item->create();  
            $this->branch[$this->name][]=$arr;  
        }  
        if(empty($this->branch)){  
            $this->branch[$this->name]=array();  
        }  
        return $this->branch;  
    }  
      
    public function combination(tree $item){  
        $this->items[]=$item;  
    }  
      
    public function separation(tree $item){  
        $key=array_search($item,$this->items);  
        if($key!==false){  
            unset($this->items[$key]);  
        }  
    }  
  
}  
  
$leaf_1=new createLeaf('大红树叶','大','红');  
$leaf_2=new createLeaf('大绿树叶','大','绿');  
$leaf_3=new createLeaf('大黄树叶','大','黄');  
  
$leaf_4=new createLeaf('小红树叶','小','红');  
$leaf_5=new createLeaf('小绿树叶','小','绿');  
$leaf_6=new createLeaf('小黄树叶','小','黄');  
  
$branch_1=new createBranch('树枝1号');  
$branch_1->combination($leaf_1);  
$branch_1->combination($leaf_2);  
$branch_1->combination($leaf_3);  
  
$branch_2=new createBranch('树枝2号');  
$branch_2->combination($leaf_4);  
$branch_2->combination($leaf_5);  
$branch_2->combination($leaf_6);  
  
$branch=new createBranch('树干');  
$branch->combination($branch_1);  
$branch->combination($branch_2);  
  
print_r($branch->create());  
  
运行以上代码将得到:  
  
Array  
(  
    [树干] => Array  
        (  
            [0] => Array  
                (  
                    [树枝1号] => Array  
                        (  
                            [0] => Array  
                                (  
                                    [大红树叶] => Array  
                                        (  
                                            [size] => 大  
                                            [color] => 红  
                                        )  
  
                                )  
  
                            [1] => Array  
                                (  
                                    [大绿树叶] => Array  
                                        (  
                                            [size] => 大  
                                            [color] => 绿  
                                        )  
  
                                )  
  
                            [2] => Array  
                                (  
                                    [大黄树叶] => Array  
                                        (  
                                            [size] => 大  
                                            [color] => 黄  
                                        )  
  
                                )  
  
                        )  
  
                )  
  
            [1] => Array  
                (  
                    [树枝2号] => Array  
                        (  
                            [0] => Array  
                                (  
                                    [小红树叶] => Array  
                                        (  
                                            [size] => 小  
                                            [color] => 红  
                                        )  
  
                                )  
  
                            [1] => Array  
                                (  
                                    [小绿树叶] => Array  
                                        (  
                                            [size] => 小  
                                            [color] => 绿  
                                        )  
  
                                )  
  
                            [2] => Array  
                                (  
                                    [小黄树叶] => Array  
                                        (  
                                            [size] => 小  
                                            [color] => 黄  
                                        )  
  
                                )  
  
                        )  
  
                )  
  
        )  
  
)

이 요구 사항을 훌륭하게 완료하여 큰 나무가 만들어졌지만 여기에 문제가 있습니다. 나뭇잎을 만들려면 create() 작업만 필요하고 조합()과 분리()는 필요하지 않습니다. 추상 클래스 트리를 두 클래스로 나누는 것은 어떻습니까?

abstract class tree{  
    abstract function create();  
}  
  
//拆分出的树干抽象类,由于继承自tree,必须将create()实现,但实现create()又会造成代码重复,所以将此类也申明为抽象类  
abstract class branch extends tree{  
    abstract function combination(tree $item);  
    abstract function separation(tree $item);  
}  
  
class createLeaf extends tree{  
      
    private $name;  
    private $size;  
    private $color;  
    private $leaf=array();  
      
    public function __construct($name,$size,$color){  
        $this->name=$name;  
        $this->size=$size;  
        $this->color=$color;  
    }  
      
    public function create(){  
        $this->leaf[$this->name]=array(  
            'size'=>$this->size,  
            'color'=>$this->color  
        );  
        return $this->leaf;  
    }  
      
    public function combination(tree $item){  
        throw new Exception("本类不支持组合操作");  
    }  
      
    public function separation(tree $item){  
        throw new Exception("本类不支持分离操作");  
    }  
      
}  
  
class createBranch extends branch{  
  
    private $name;  
    private $branch=array();  
    private $items=array();  
      
    public function __construct($name){  
        $this->name=$name;  
    }  
      
    public function create(){  
        foreach($this->items as $item){  
            $arr=$item->create();  
            $this->branch[$this->name][]=$arr;  
        }  
        if(empty($this->branch)){  
            $this->branch[$this->name]=array();  
        }  
        return $this->branch;  
    }  
      
    public function combination(tree $item){  
        $this->items[]=$item;  
    }  
      
    public function separation(tree $item){  
        $key=array_search($item,$this->items);  
        if($key!==false){  
            unset($this->items[$key]);  
        }  
    }  
  
}  
  
$leaf_1=new createLeaf('大红树叶','大','红');  
$leaf_2=new createLeaf('大绿树叶','大','绿');  
$leaf_3=new createLeaf('大黄树叶','大','黄');  
  
$leaf_4=new createLeaf('小红树叶','小','红');  
$leaf_5=new createLeaf('小绿树叶','小','绿');  
$leaf_6=new createLeaf('小黄树叶','小','黄');  
  
$branch_1=new createBranch('树枝1号');  
$branch_1->combination($leaf_1);  
$branch_1->combination($leaf_2);  
$branch_1->combination($leaf_3);  
  
$branch_2=new createBranch('树枝2号');  
$branch_2->combination($leaf_4);  
$branch_2->combination($leaf_5);  
$branch_2->combination($leaf_6);  
  
$branch=new createBranch('树干');  
$branch->combination($branch_1);  
$branch->combination($branch_2);  
  
print_r($branch->create());

이렇게 해서 우리는 마침내 이 요구 사항을 훌륭하게 충족시켰습니다. 하지만 구성 패턴의 유연성으로 인해 많은 사람들이 생각 없이 구성 클래스를 사용하는 것을 좋아한다는 점에 유의해야 합니다. 실제로 조합 클래스에는 "너무 유연하다"고 "오버헤드가 높다"는 단점이 있습니다. 요소나 조합이 시스템 전체에서 여러 번 호출될 수 있지만 일단 시스템의 한 노드에서 특정 요소나 조합에 문제가 발생하면 해당 노드의 문제를 해결하기 어려울 것이라고 가정해 보겠습니다.

다시 상상해 보세요. 시스템의 특정 요소가 데이터베이스를 쿼리하는 SQL 문이고, 이 SQL 문의 오버헤드가 다소 높다면, 전체 시스템 구석구석에 결합되면 시스템을 실행한 결과 재앙이 될 것입니다.

관련 권장사항:

PHP 디자인 패턴 조합 모드

PHP 디자인 패턴 조합 모드 및 대소문자 공유

PHP 방문자 모드 및 조합 모드에 대한 자세한 설명

위 내용은 PHP 조합 모드에 대한 자세한 설명 및 사례의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.