Home  >  Article  >  Backend Development  >  Detailed explanation and cases of PHP combination mode

Detailed explanation and cases of PHP combination mode

墨辰丷
墨辰丷Original
2018-05-16 14:29:171459browse

This article mainly introduces the detailed explanation and cases of PHP combination mode. Interested friends can refer to it. I hope it will be helpful to everyone.

This model can be somewhat ambiguous to understand, especially the difficult explanations in some books. Let’s first talk about several characteristics of the combination model:

1. There must be indivisible basic elements.

2. The combined objects can be combined.

To give a popular example, atoms are the basic particles of chemical reactions, and they are indivisible in chemical reactions. There are now four types of atoms, C (carbon), H (hydrogen), O (oxygen), and N (nitrogen), which can be randomly combined into countless molecules, either protein or fat. Protein and fat are combinations. Protein and fat can be combined into meat, soybeans, etc.

Back to the topic, now there is a requirement. The customer needs to create a leaf. The size and color of the leaf can be set, and the leaf can be named.

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] => 红  
        )  
  
)

Our design perfectly fulfilled the customer's needs, but now the customer's new requirements are coming, not only to be able to create leaves, but also to be able to create branches, and to be able to place leaves on the branches, You can also remove the installed leaves from the branches. What they ultimately want is that other branches can be placed on the branches to build a leafy tree


Analysis: Creating leaves and creating branches are both They have creation operations, so they can all implement the abstract tree class, but the class that creates branches also needs insertion and removal operations, so for now we add two abstract methods combination() and separation() to the tree class.

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] => 黄  
                                        )  
  
                                )  
  
                        )  
  
                )  
  
        )  
  
)

We completed this requirement beautifully, and a big tree was created by us, but there is a problem here. Creating leaves only requires the create() operation, and does not require combination() and separation(). , why don't we split the abstract class tree into two classes?

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());

In this way, we finally fulfilled this requirement beautifully. But it must be noted that due to the flexibility of the composition pattern, many people like to use composition classes without thinking. In fact, the combination class has the defects of "too flexible" and "high overhead". Let's imagine that an element or combination may be called many times throughout the system, but once there is a problem with a certain element or combination at a node in the system, it will be difficult for us to troubleshoot that node.

Imagine again, if a certain element in the system is a SQL statement that queries the database, and the overhead of this SQL statement is somewhat high, once it is combined into every corner of the entire system, the running system will cause The results will be catastrophic.

Related recommendations:

PHP Design Patterns Combination Patterns

PHP Design Patterns Combination Patterns and Case Sharing

Detailed explanation of PHP visitor mode and combination mode

The above is the detailed content of Detailed explanation and cases of PHP combination mode. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn