Maison  >  Article  >  développement back-end  >  Explication détaillée et cas du mode combinaison PHP

Explication détaillée et cas du mode combinaison PHP

墨辰丷
墨辰丷original
2018-05-16 14:29:171564parcourir

Cet article présente principalement l'explication détaillée et les cas du mode combinaison PHP. Les amis intéressés peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

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 : Créer des feuilles et créer des branches sont tous les deux Ils ont des opérations de création, donc ils peuvent tous implémenter la classe arbre abstrait, mais la classe qui crée des branches a également besoin d'opérations d'insertion et de suppression, donc pour le moment, nous ajoutons deux méthodes abstraites combinaison() et séparation() à la classe arbre.

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 nous avons créé un grand arbre, mais il y a un problème. La création de feuilles ne nécessite que l'opération create(), et ne nécessite pas de combinaison() ni de séparation. (), pourquoi ne pas diviser 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 a 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 catastrophiques.

Recommandations associées :

Modèles de combinaison de modèles de conception PHP

Modèles de combinaison de modèles de conception PHP et partage de cas

Explication détaillée du mode visiteur PHP et du mode combinaison

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn