PHP combination model Details and cases

Source: Internet
Author: User
Tags abstract tree
This article mainly introduces the PHP combination pattern detailed and the case, the interest friend's reference, hoped to have the help to everybody.

This pattern is somewhat ambiguous, especially in some books, which are difficult to understand. First of all, there are several features of the combinatorial pattern:

1, must exist indivisible basic elements.

2, the combination of objects can be combined.

In a popular example, an atom is a basic particle of a chemical reaction that is inseparable from a chemical reaction. Now there are C (carbon), H (hydrogen), O (Oxygen), N (nitrogen) 4 kinds of atoms, they can be randomly combined into countless kinds of molecules, can be protein, also can be fat, protein and fat is a combination. The protein and fat can be combined into meat, soybeans and so on.

Back to the topic, there is now a need for customers to create a leaf that can set the leaf size and color, and can be named for the leaf.

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 (' Scarlet leaves ', ' big ', ' red ');    Print_r ($leaf->create ());    Run the above code to get:      array  (      [red leaf] = = Array          (              [size] =    [[Color] = [] + red)]

Our design is perfect to achieve the customer's needs, but, now the customer's new requirements come, not only to create leaves, but also to create branches, and, can be placed on the branches of leaves, can also be planted in the leaves from the branches removed. They eventually wanted the result that other branches could be planted on the branches to create a leafy tree.


Parsing: Creating leaves and creating branches all have create operations, so they can all be implemented on abstract tree classes, but the class that creates the branches also needs to be placed and removed, so let's add two abstract methods combination () and separation () to the tree.

Abstract class tree{abstract function Create ();//Creating an abstract function combination (tree $item);//Combination Abstrac      t function separation (tree $item);//Detach} 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->si          Ze, ' color ' = $this->color);      return $this->leaf;          }//Because creating a leaf class does not require combining and separating operations, we throw these two methods out of error warnings.      Public function combination (tree $item) {throw new Exception ("This class does not support combined operations");      } Public Function separation (tree $item) {throw new Exception ("This class does not support detach operation");      }} class Createbranch extends tree{private $name; Private $BRAnch=array (); Private $items =array ();//branches may be planted with leaves, which are used to store leaf objects public function __construct ($name) {$this->name= $nam      E }///We already know that the objects within the $items contain the create operation, so as long as the creation of each object is executed sequentially, the results can be collected as public function create () {foreach ($this->i              TEMs as $item) {$arr = $item->create ();          $this->branch[$this->name][]= $arr;          } if (Empty ($this->branch)) {$this->branch[$this->name]=array ();      } return $this->branch;      The Public function combination (tree $item) {$this->items[]= $item;          The Public Function separation (tree $item) {$key =array_search ($item, $this->items);          if ($key!==false) {unset ($this->items[$key]);  }}} $leaf _1=new createleaf (' Scarlet leaf ', ' big ', ' red ');  $leaf _2=new createleaf (' Big green leaves ', ' big ', ' green ');    $leaf _3=new createleaf (' rhubarb leaves ', ' big ', ' yellow ');  $leaf _4=new createleaf (' Little Red leaves ', ' small ', ' red '); $leaf _5=New Createleaf (' Little green leaves ', ' small ', ' green ');    $leaf _6=new createleaf (' Small yellow leaves ', ' small ', ' yellow ');  $branch _1=new createbranch (' Branch no. 1th ');  $branch _1->combination ($leaf _1);  $branch _1->combination ($leaf _2);    $branch _1->combination ($leaf _3);  $branch _2=new createbranch (' Branch No. 2nd ');  $branch _2->combination ($leaf _4);  $branch _2->combination ($leaf _5);    $branch _2->combination ($leaf _6);  $branch =new createbranch (' trunk ');  $branch->combination ($branch _1);    $branch->combination ($branch _2);    Print_r ($branch->create ());                      Running the above code will get: Array ([trunk] = = Array ([0] = = Array (                                  [Branch No. 1th] = = Array ([0] = = Array                                              ([red leaf] = = Array (           [Size] = large [color] + red                               )) [1] = = Array                                          ([Big green leaf] = = Array ([size] = large [color] =& Gt  Green)) [2] = =                                          Array ([rhubarb leaf] = = Array                                              ([size] = large                            [Color] = yellow))                          )) [1] = = Array ([branch no. 2nd] = = Array (                              [0] = = Array ([small mangrove                                              Leaf] = = Array ([size] = Small                                    [Color] = red)                                      ) [1] = = Array ( [small green leaves] = = Array ([si                                    Ze] = small [color] = green)                                      ) [2] = = Array (                                              [small yellow leaves] = = Array ( [Size] =>                                    small [color] = yellow) )                            )                    )            )    )

We beautifully finished this demand, a tree of heaven was created by us, but there is a problem, the creation of leaves operation only need to create () operation, do not need combination () and separation (), why we do not split the abstract class tree into two classes?

Abstract class tree{abstract function Create (); }//Split trunk abstract class, due to inherit from tree, must be the Create () implementation, but the implementation of create () will cause code duplication, so this class is also declared abstract class branch extends tree{Abstra      CT 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->si          Ze, ' color ' = $this->color);      return $this->leaf;      The Public function combination (tree $item) {throw new Exception ("This class does not support combined operations");      } Public Function separation (tree $item) {throw new Exception ("This class does not support detach operation"); }} 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;      The Public function combination (tree $item) {$this->items[]= $item;          The Public Function separation (tree $item) {$key =array_search ($item, $this->items);          if ($key!==false) {unset ($this->items[$key]);  }}} $leaf _1=new createleaf (' Scarlet leaf ', ' big ', ' red ');  $leaf _2=new createleaf (' Big green leaves ', ' big ', ' green ');    $leaf _3=new createleaf (' rhubarb leaves ', ' big ', ' yellow ');  $leaf _4=new createleaf (' Little Red leaves ', ' small ', ' red '); $leaf _5=new createleaf (' Little green TreesLeaves ', ' small ', ' green ');    $leaf _6=new createleaf (' Small yellow leaves ', ' small ', ' yellow ');  $branch _1=new createbranch (' Branch no. 1th ');  $branch _1->combination ($leaf _1);  $branch _1->combination ($leaf _2);    $branch _1->combination ($leaf _3);  $branch _2=new createbranch (' Branch No. 2nd ');  $branch _2->combination ($leaf _4);  $branch _2->combination ($leaf _5);    $branch _2->combination ($leaf _6);  $branch =new createbranch (' trunk ');  $branch->combination ($branch _1);    $branch->combination ($branch _2); Print_r ($branch->create ());

In this way, we are finally pretty finished with this requirement. However, it is important to note that because of the flexibility of the combined mode, many people prefer to use combinatorial classes without hesitation. In fact, there is a flaw in the combinatorial class that is "too flexible" and "expensive". Let's just imagine that an element or a combination may be called very many times throughout the system, but once an element or combination of a node in the system has a problem, it's hard to troubleshoot that node.

Imagine, if an element in the system is a SQL statement that queries the database, and the cost of the SQL statement is a bit large, once it is grouped into every corner of the system, the result of the operating system will be catastrophic.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.