Dieses Modell kann etwas unklar sein, insbesondere die schwierigen Erklärungen in manchen Büchern. Lassen Sie uns zunächst über einige Merkmale des Kombinationsmodells sprechen:
1. Es müssen unteilbare Grundelemente vorhanden sein.
2. Die kombinierten Objekte können kombiniert werden.
Um ein beliebtes Beispiel zu nennen: Atome sind die Grundteilchen chemischer Reaktionen und bei chemischen Reaktionen unteilbar. Es gibt jetzt vier Arten von Atomen, C (Kohlenstoff), H (Wasserstoff), O (Sauerstoff) und N (Stickstoff), die zufällig zu unzähligen Molekülen kombiniert werden können, entweder Protein oder Fett. Protein und Fett sind Kombinationen. Eiweiß und Fett können in Fleisch, Sojabohnen usw. kombiniert werden.
Zurück zum Thema, jetzt muss der Kunde ein Blatt erstellen. Die Größe und Farbe des Blattes kann festgelegt werden.
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] => 红 ) )
Unser Design hat die Bedürfnisse des Kunden perfekt erfüllt, aber jetzt kommen die neuen Anforderungen des Kunden, nicht nur Blätter erstellen zu können, sondern auch Zweige erstellen und platzieren zu können Blätter an Ästen Sie können die angebrachten Blätter auch von den Ästen entfernen. Was sie letztendlich wollen, ist, dass andere Zweige auf den Zweigen platziert werden können, um einen Blattbaum zu erstellen.
Analyse: Das Erstellen von Blättern und das Erstellen von Zweigen verfügen beide über Erstellungsoperationen, sodass beides möglich ist. Die abstrakte Baumklasse ist implementiert, aber die Die Klasse, die die Zweige erstellt, erfordert auch Einfüge- und Entfernungsoperationen, daher fügen wir der Baumklasse vorübergehend zwei abstrakte Methodenkombination() und Trennung() hinzu.
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] => 黄 ) ) ) ) ) )
Wir haben diese Anforderung wunderbar erfüllt und einen großen Baum erstellt
, aber hier gibt es ein Problem. Für die Erstellung von Blättern ist nur die Operation „create()“ und nicht „Combination()“ erforderlich separat() benötigt werden, warum teilen wir den abstrakten Klassenbaum nicht in zwei Klassen auf?
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());
Auf diese Weise haben wir diese Anforderung endlich wunderbar erfüllt. Es muss jedoch beachtet werden, dass viele Menschen Kompositionsklassen aufgrund der Flexibilität des Kompositionsmusters gerne ohne nachzudenken verwenden. Tatsächlich weist die Kombinationsklasse die Mängel „zu flexibel“ und „hoher Overhead“ auf. Stellen wir uns vor, dass ein Element oder eine Kombination im gesamten System viele Male aufgerufen wird, aber sobald an einem Knoten im System ein Problem mit einem bestimmten Element oder einer bestimmten Kombination auftritt, wird es für uns schwierig sein, diesen Knoten zu beheben.
Stellen Sie sich noch einmal vor, wenn ein bestimmtes Element im System eine SQL-Anweisung ist, die die Datenbank abfragt, und der Overhead dieser SQL-Anweisung etwas hoch ist, wird sie ausgeführt, sobald sie in jede Ecke des gesamten Systems integriert wird Das System wird dazu führen, dass die Ergebnisse katastrophal sein werden.
Das Obige ist der Inhalt der objektorientierten PHP-Entwicklung - Kombinationsmodus. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (m.sbmmt.com).