设计模式 | 组合模式

简介: 设计模式 | 组合模式

说明

模式定义: 组合模式(Composite Pattern)有时候又叫做部分-整体模式,用于将对象组合成树形结构以表示“部分-整体”的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。

常见使用场景:如树形菜单、文件夹菜单、部门组织架构图等。

说到树形就需要先说说树的基本构成:

  • 根节点

是树的一个组成部分,也叫树根。它是同一棵树中除本身外所有结点的祖先,没有父结点。

  • 叶子结点

一棵树当中没有子结点(即度为0)的结点。 叶子是指度为0的结点,又称为终端结点。

  • 子树

子树就是树的其中一个节点以及其下面的所有的节点所构成的树

组合模式结构说明

在组合模式中有三个角色, ComponentLeafComposite, 我们分别看一下

  • Component

这是组合模式中对象声明的接口, 在适当情况下, 实现所有类共有的接口默认行为, 用于访问和管理Component部件, Component可以是抽象类或者接口。

  • Leaf

在组合中表示叶子结点, 叶子结点没有子节点

  • Composite

非叶子结点, 用于存储子部件, 在Component接口中实现子部件的相关操作, 比如增加

示例

编写程序展示一个学校的院系结构,需求: 要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系

1. <?php
2. /**
3.  *<?php
/**
 * Created by 憧憬.
 */
abstract class OrganizationComponent {
    private $name;
    private $des;
    /**
     * OrganizationComponent constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        $this->name = $name;
        $this->des = $des;
    }
    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * @param mixed $name
     */
    public function setName($name): void
    {
        $this->name = $name;
    }
    /**
     * @return mixed
     */
    public function getDes()
    {
        return $this->des;
    }
    /**
     * @param mixed $des
     */
    public function setDes($des): void
    {
        $this->des = $des;
    }
    /**
     * 添加
     * @param OrganizationComponent $organizationComponent
     * @throws Exception
     * @author: 憧憬
     */
    public function add(OrganizationComponent $organizationComponent)
    {
        throw new Exception('没有add');
    }
    /**
     * 删除
     * @param OrganizationComponent $organizationComponent
     * @throws Exception
     * @author: 憧憬
     */
    public function remove(OrganizationComponent $organizationComponent)
    {
        throw new Exception('没有remove');
    }
    /**
     * 输出
     * @return mixed
     * @author: 憧憬
     */
    abstract public function iprint();
}
/**
 * 大学
 * 是Composite角色, 可以管理College
 * Class University
 */
class University extends OrganizationComponent {
    public $organizationComponents;
    /**
     * University constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function add(OrganizationComponent $organizationComponent)
    {
        $this->organizationComponents[] = $organizationComponent;
    }
    public function remove(OrganizationComponent $organizationComponent)
    {
        foreach ($this->organizationComponents as $k => $component) {
            if ($component == $organizationComponent) {
                unset($this->organizationComponents[$k]);
            }
        }
    }
    public function getName()
    {
        return parent::getName(); // TODO: Change the autogenerated stub
    }
    public function getDes()
    {
        return parent::getDes(); // TODO: Change the autogenerated stub
    }
    /**
     * 输出University 包含的学院
     * @return mixed|void
     * @author: 憧憬
     */
    public function iprint()
    {
        echo '---------------'. $this->getName() .'--------学校' . PHP_EOL;
        foreach ($this->organizationComponents as $component) {
            $component->iprint();
        }
    }
}
/**
 * 学院
 * Class College
 */
class College extends OrganizationComponent {
    // 包含的college
    public $organizationComponents;
    /**
     * University constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function add(OrganizationComponent $organizationComponent)
    {
        $this->organizationComponents[] = $organizationComponent;
    }
    public function remove(OrganizationComponent $organizationComponent)
    {
        foreach ($this->organizationComponents as $k => $component) {
            if ($component == $organizationComponent) {
                unset($this->organizationComponents[$k]);
            }
        }
    }
    public function getName()
    {
        return parent::getName(); // TODO: Change the autogenerated stub
    }
    public function getDes()
    {
        return parent::getDes(); // TODO: Change the autogenerated stub
    }
    /**
     * 输出University 包含的系
     * @return mixed|void
     * @author: 憧憬
     */
    public function iprint()
    {
        echo '---------------'. $this->getName() .'-------学院' . PHP_EOL;
        foreach ($this->organizationComponents as $component) {
            $component->iprint();
        }
    }
}
/**
 * 系 属于叶子结点 所以不需要重写add和remove
 * Class Department
 */
class Department extends OrganizationComponent {
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function iprint()
    {
        // TODO: Implement iprint() method.
        echo '-------------'.$this->getName(). '--------系'.PHP_EOL;
    }
}
// 创建学校
$university = new University('清华大学', '中国顶级大学');
// 创建学院
$computerCollege = new College('计算机学院', '计算机学院');
$infoEngineerCollege = new College('信息工程学院', '信息工程学院');
// 创建学院下的个个系
$computerCollege->add(new Department('软件工程', '软件工程ok'));
$computerCollege->add(new Department('网络工程', '网络工程ok'));
$computerCollege->add(new Department('计算机科学与技术', '计算机科学与技术ok'));
$infoEngineerCollege->add(new Department('通信工程', '通信工程不ok'));
$infoEngineerCollege->add(new Department('信息工程', '信息工程不ok'));
// 将学院加入学校
$university->add($computerCollege);
$university->add($infoEngineerCollege);
// 输出整个大学下面的子节点
$university->iprint();
echo PHP_EOL;
// 输出计算机学院下面的子节点
$computerCollege->iprint();
// 如果再要强化级别 只需要接着实现 组合进来就可以 比较方便 Created by 憧憬.
4.  */
5. 
6. 
7. abstract class OrganizationComponent {
8. private $name;
9. private $des;
10. 
11. /**
12.      * OrganizationComponent constructor.
13.      * @param $name
14.      * @param $des
15.      */
16. public function __construct($name, $des)
17.     {
18. $this->name = $name;
19. $this->des = $des;
20.     }
21. 
22. /**
23.      * @return mixed
24.      */
25. public function getName()
26.     {
27. return $this->name;
28.     }
29. 
30. /**
31.      * @param mixed $name
32.      */
33. public function setName($name): void
34.     {
35. $this->name = $name;
36.     }
37. 
38. /**
39.      * @return mixed
40.      */
41. public function getDes()
42.     {
43. return $this->des;
44.     }
45. 
46. /**
47.      * @param mixed $des
48.      */
49. public function setDes($des): void
50.     {
51. $this->des = $des;
52.     }
53. 
54. 
55. /**
56.      * 添加
57.      * @param OrganizationComponent $organizationComponent
58.      * @throws Exception
59.      * @author: 憧憬
60.      */
61. public function add(OrganizationComponent $organizationComponent)
62.     {
63. throw new Exception('没有add');
64.     }
65. 
66. 
67. /**
68.      * 删除
69.      * @param OrganizationComponent $organizationComponent
70.      * @throws Exception
71.      * @author: 憧憬
72.      */
73. public function remove(OrganizationComponent $organizationComponent)
74.     {
75. throw new Exception('没有remove');
76.     }
77. 
78. 
79. /**
80.      * 输出
81.      * @return mixed
82.      * @author: 憧憬
83.      */
84. abstract public function iprint();
85. }
86. 
87. 
88. /**
89.  * 大学
90.  * 是Composite角色, 可以管理College
91.  * Class University
92.  */
93. class University extends OrganizationComponent {
94. 
95. public $organizationComponents;
96. 
97. /**
98.      * University constructor.
99.      * @param $name
100.      * @param $des
101.      */
102. public function __construct($name, $des)
103.     {
104. parent::__construct($name, $des);
105. $this->organizationComponents = [];
106.     }
107. 
108. public function add(OrganizationComponent $organizationComponent)
109.     {
110. $this->organizationComponents[] = $organizationComponent;
111.     }
112. 
113. public function remove(OrganizationComponent $organizationComponent)
114.     {
115. foreach ($this->organizationComponents as $k => $component) {
116. if ($component == $organizationComponent) {
117. unset($this->organizationComponents[$k]);
118.             }
119.         }
120.     }
121. 
122. public function getName()
123.     {
124. return parent::getName(); // TODO: Change the autogenerated stub
125.     }
126. 
127. public function getDes()
128.     {
129. return parent::getDes(); // TODO: Change the autogenerated stub
130.     }
131. 
132. /**
133.      * 输出University 包含的学院
134.      * @return mixed|void
135.      * @author: 憧憬
136.      */
137. public function iprint()
138.     {
139. echo '---------------'. $this->getName() .'--------学校' . PHP_EOL;
140. 
141. foreach ($this->organizationComponents as $component) {
142. $component->iprint();
143.         }
144.     }
145. 
146. }
147. 
148. 
149. /**
150.  * 学院
151.  * Class College
152.  */
153. class College extends OrganizationComponent {
154. 
155. // 包含的college
156. public $organizationComponents;
157. 
158. /**
159.      * University constructor.
160.      * @param $name
161.      * @param $des
162.      */
163. public function __construct($name, $des)
164.     {
165. parent::__construct($name, $des);
166. $this->organizationComponents = [];
167.     }
168. 
169. public function add(OrganizationComponent $organizationComponent)
170.     {
171. $this->organizationComponents[] = $organizationComponent;
172.     }
173. 
174. public function remove(OrganizationComponent $organizationComponent)
175.     {
176. foreach ($this->organizationComponents as $k => $component) {
177. if ($component == $organizationComponent) {
178. unset($this->organizationComponents[$k]);
179.             }
180.         }
181.     }
182. 
183. public function getName()
184.     {
185. return parent::getName(); // TODO: Change the autogenerated stub
186.     }
187. 
188. public function getDes()
189.     {
190. return parent::getDes(); // TODO: Change the autogenerated stub
191.     }
192. 
193. /**
194.      * 输出University 包含的系
195.      * @return mixed|void
196.      * @author: 憧憬
197.      */
198. public function iprint()
199.     {
200. echo '---------------'. $this->getName() .'-------学院' . PHP_EOL;
201. 
202. foreach ($this->organizationComponents as $component) {
203. $component->iprint();
204.         }
205.     }
206. 
207. }
208. 
209. 
210. /**
211.  * 系 属于叶子结点 所以不需要重写add和remove
212.  * Class Department
213.  */
214. class Department extends OrganizationComponent {
215. 
216. 
217. public function __construct($name, $des)
218.     {
219. parent::__construct($name, $des);
220. $this->organizationComponents = [];
221.     }
222. 
223. 
224. public function iprint()
225.     {
226. // TODO: Implement iprint() method.
227. echo '-------------'.$this->getName(). '--------系'.PHP_EOL;
228.     }
229. 
230. }
231. 
232. // 创建学校
233. $university = new University('清华大学', '中国顶级大学');
234. 
235. // 创建学院
236. $computerCollege = new College('计算机学院', '计算机学院');
237. $infoEngineerCollege = new College('信息工程学院', '信息工程学院');
238. 
239. 
240. 
241. // 创建学院下的个个系
242. $computerCollege->add(new Department('软件工程', '软件工程ok'));
243. $computerCollege->add(new Department('网络工程', '网络工程ok'));
244. $computerCollege->add(new Department('计算机科学与技术', '计算机科学与技术ok'));
245. $infoEngineerCollege->add(new Department('通信工程', '通信工程不ok'));
246. $infoEngineerCollege->add(new Department('信息工程', '信息工程不ok'));
247. 
248. // 将学院加入学校
249. $university->add($computerCollege);
250. $university->add($infoEngineerCollege);
251. 
252. 
253. // 输出整个大学下面的子节点
254. $university->iprint();
255. 
256. echo PHP_EOL;
257. 
258. // 输出计算机学院下面的子节点
259. $computerCollege->iprint();
260. 
261. // 如果再要强化级别 只需要接着实现 组合进来就可以 比较方便
目录
相关文章
|
4月前
|
设计模式
二十三种设计模式全面解析-解密组合模式(Composite Pattern):构建统一而强大的对象结构
二十三种设计模式全面解析-解密组合模式(Composite Pattern):构建统一而强大的对象结构
|
6月前
|
设计模式 存储 安全
结构型设计模式05-组合模式
结构型设计模式05-组合模式
18 0
|
4月前
|
设计模式
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
|
4月前
|
设计模式
二十三种设计模式全面解析-组合模式与迭代器模式的结合应用:构建灵活可扩展的对象结构
二十三种设计模式全面解析-组合模式与迭代器模式的结合应用:构建灵活可扩展的对象结构
|
6天前
|
设计模式 Java 容器
【设计模式系列笔记】组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构以表示部分-整体的层次结构。组合模式使得客户端可以统一处理单个对象和对象组合,而无需区分它们的类型。
38 12
|
15天前
|
设计模式 Java
小谈设计模式(20)—组合模式
小谈设计模式(20)—组合模式
|
4月前
|
设计模式 Java
Java设计模式【九】:组合模式
Java设计模式【九】:组合模式
30 0
|
1月前
|
设计模式 JavaScript uml
设计模式之组合模式
设计模式之组合模式
设计模式之组合模式
|
1月前
|
设计模式 存储 安全
【设计模式】组合模式
【设计模式】组合模式
|
2月前
|
设计模式 Java
浅谈设计模式 - 组合模式(十二)
浅谈设计模式 - 组合模式(十二)
51 0