This pattern may be ambiguous, especially those hard to understand in some books. Let's first talk about the characteristics of the combination mode: This mode may be ambiguous in understanding, especially those difficult to understand in some books. Let's talk about the characteristics of the combination mode:
1. an inseparable basic element must exist.
2. the combined object can be combined.
For example, atoms are the basic particles of chemical reactions, which are inseparable from each other. There are now four kinds of atoms: C (carbon), H (hydrogen), O (oxygen), and N (nitrogen). They can be randomly combined into countless molecules, which can be proteins, it can also be fat, and protein and fat are combinations. Protein and fat can be combined into meat, soy, and so on.
Back to the theme, there is now a requirement that the customer needs to create a leaf, which can set the leaf size and color and name 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 ('Big leaf ', 'Big', 'red'); print_r ($ leaf-> create ()); run the above code to get: Array ([red leaves] => Array ([size] => large [color] => Red ))
Our design perfectly meets the customer's needs, but now the customer's new requirements come, not only to be able to create leaves, but also to create branches, and to put the leaves on the branches, you can also remove the inserted leaves from the branches. In the end, they wanted to build a tree with dense leaves by inserting other branches on the branches.
Analysis: both creating leaves and creating branches have creation operations, so they can all implement the abstract tree class. However, you also need to install and remove the class for creating branches, therefore, we will add two abstract methods combination () and separation () to the tree class ().
Abstract class tree {abstract function create (); // create abstract function combination (tree $ item); // combine abstract function separation (tree $ item ); // separation} 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 ;} // because the combination and separation operations are not required to create leaf classes, we throw an error warning for these two methods. Public function combination (tree $ item) {throw new Exception ("This class does not support combination operation");} public function separation (tree $ item) {throw new Exception ("This class does not support separation operations") ;}} class createBranch extends tree {private $ name; private $ branch = array (); private $ items = array (); // the branches may be inserted with leaves. this variable is used to store the leaf object public function _ construct ($ name) {$ this-> name = $ name;} // we already know that all objects in $ items contain creation operations. Therefore, you only need to perform creation operations on each object in sequence, you can use the public function crere to collect results. Ate () {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 ('red leaf ', 'day ', 'Red'); $ leaf_2 = new createLeaf ('Big Green Leaf ', 'Big', 'green'); $ leaf_3 = new createLeaf ('Rhubarb leaf ', 'Big ', 'Yellow '); $ leaf_4 = new createLeaf ('small red leaf', 'small ', 'red'); $ leaf_5 = new createLeaf ('small green leaf', 'small ', 'Green'); $ leaf_6 = new createLeaf ('small yellow leaf ', 'small', 'Yellow '); $ branch_1 = new createBranch ('branch 1 '); $ branch_1-> combination ($ leaf_1); $ branch_1-> combination ($ leaf_2); $ branch_1-> combination ($ leaf_3 ); $ branch_2 = new createBranch ('branch2'); $ 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 (); run the above code to get: array ([trunk] => Array ([0] => Array ([branches 1] => Array ([0] => Array ([red leaf] => Array ([size] => large [color] => Red )) [1] => Array ([big green leaves] => Array ([size] => big [color] => Green )) [2] => Array ([rhubarb leaves] => Array ([size] => large [color] => yellow )))) [1] => Array ([branch 2] => Array ([0] => Array ([small red leaves] => Array ([size] => small [color] => Red )) [1] => Array ([small green leaves] => Array ([size] => small [color] => Green )) [2] => Array ([small yellow leaves] => Array ([size] => small [color] => yellow ))))))
We successfully completed this requirement, and a huge treasure was created by us.
But there is a problem here. the create leaf operation 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 () ;}// the abstract class of the tree trunk that is split out. because it inherits from the tree, create () must be implemented, but create () must be implemented () this class is also declared as 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 = $ n Ame; $ 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 ("this class does not support combination operation");} public function separation (tree $ item) {throw new Exception ("This class does not support separation operations") ;}} 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 = ar Ray_search ($ item, $ this-> items); if ($ key! = False) {unset ($ this-> items [$ key]) ;}}$ leaf_1 = new createLeaf ('red leaf ', 'day ', 'Red'); $ leaf_2 = new createLeaf ('Big Green Leaf ', 'Big', 'green'); $ leaf_3 = new createLeaf ('Rhubarb leaf ', 'Big ', 'Yellow '); $ leaf_4 = new createLeaf ('small red leaf', 'small ', 'red'); $ leaf_5 = new createLeaf ('small green leaf', 'small ', 'Green'); $ leaf_6 = new createLeaf ('small yellow leaf ', 'small', 'Yellow '); $ branch_1 = new createBranch ('branch 1 '); $ branch_1-> combination ($ leaf_1); $ branch_1-> combination ($ leaf_2); $ branch_1-> combination ($ leaf_3 ); $ branch_2 = new createBranch ('branch2'); $ 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 have successfully completed this requirement. However, due to the flexibility of the combination mode, many people prefer to use the combination class without thinking about it. In fact, the combination class has the defect of "too flexible" and "high overhead. We can imagine that an element or combination may be called many times in the entire system, but once an element or combination has a problem on a node in the system, we can hardly find the node.
Try again, if an element in the system is an SQL statement for querying the database, and the overhead of this SQL statement is a little large, once it is combined into every corner of the system, the results of running the system will be disastrous.
The above is php object-oriented development-the content of the combination mode. For more information, see PHP Chinese network (www.php1.cn )!