Ce modèle peut être quelque peu ambigu à comprendre, notamment les explications difficiles de certains livres. Parlons d’abord de plusieurs caractéristiques du modèle de combinaison :
1 Il doit y avoir des éléments de base indivisibles.
2. Les objets combinés peuvent être combinés.
Pour donner un exemple populaire, les atomes sont les particules de base des réactions chimiques, et ils sont indivisibles dans les réactions chimiques. Il existe désormais quatre types d'atomes, C (carbone), H (hydrogène), O (oxygène) et N (azote), qui peuvent être combinés de manière aléatoire en d'innombrables molécules, soit des protéines, soit des graisses. Les protéines et les graisses sont des combinaisons. Les protéines et les graisses peuvent être combinées dans la viande, le soja, etc.
Retour au sujet, il y a maintenant une exigence. Le client doit créer une feuille. La taille et la couleur de la feuille peuvent être définies, et la feuille peut être nommée.
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] => 红 ) )
Notre conception répondait parfaitement aux besoins du client, mais maintenant les nouvelles exigences du client arrivent, non seulement pour pouvoir créer des feuilles, mais aussi pour pouvoir créer des branches, et pour pouvoir placer feuilles sur les branches Vous pouvez également supprimer les feuilles installées des branches. Ce qu'ils veulent en fin de compte, c'est que d'autres branches puissent être placées sur les branches pour construire un arbre feuillu
Analyse : La création de feuilles et la création de branches ont toutes deux des opérations de création, donc elles peuvent toutes les deux La classe d'arbre abstrait est implémentée, mais la La classe qui crée les branches nécessite également des opérations d'insertion et de suppression, donc pour le moment, nous ajoutons deux méthodes abstraites combinaison() et séparation() à la classe arborescente.
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] => 黄 ) ) ) ) ) )
Nous avons magnifiquement rempli cette exigence et un grand arbre a été créé
, mais il y a un problème ici. La création de feuilles ne nécessite que l'opération create(), pas la combinaison() et. séparation() sont nécessaires, pourquoi ne divisons-nous pas l'arborescence des classes abstraites en deux 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());
De cette façon, nous avons finalement magnifiquement rempli cette exigence. Mais il faut noter qu’en raison de la flexibilité du modèle de composition, de nombreuses personnes aiment utiliser les cours de composition sans réfléchir. En fait, la classe combinée présente les défauts de « trop flexible » et de « surcharge élevée ». Imaginons qu'un élément ou une combinaison puisse être appelé plusieurs fois dans le système, mais qu'une fois qu'il y aura un problème avec un certain élément ou une certaine combinaison au niveau d'un nœud du système, il nous sera difficile de dépanner ce nœud.
Imaginez encore une fois, si un certain élément du système est une instruction SQL qui interroge la base de données et que la surcharge de cette instruction SQL est quelque peu élevée, une fois qu'elle est combinée dans tous les coins de l'ensemble du système, l'exécution Le système provoquera Les résultats seront désastreux.
Ce qui précède est le contenu du mode de combinaison du développement orienté objet PHP. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !