forked from wenjy/design_patten_php
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Composite.php
142 lines (119 loc) · 3.26 KB
/
Composite.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/**
* 组合模式
*
* 将对象组合成树形结构已表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
*
* 当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,
* 统一地使用组合结构中的所有对象时,就应该考虑使用组合模式了。
*
* 基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去
* 在客户代码中,任何用到基本对象的地方都可以使用组合对象了。
*
* 用户是不用关心到底是处理一个叶节点还是处理一个组合组件,也就是用不着为定义只而写一些选择判断语句了。
*
* 组合模式让客户可以一致的使用组合结构和单个对象。
*
*/
/**
* 组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。
* 声明一个接口用于访问和管理 Component 的子部件
*
* Class Component
*/
abstract class Component
{
protected $name;
/**
* Component constructor.
* @param $name
*/
public function __construct($name)
{
$this->name = $name;
}
abstract public function add(Component $c);
abstract public function remove(Component $c);
abstract public function display($depth);
}
/**
* 在组合中表示叶节点对象,叶节点没有子节点
*
* Class Leaf
*/
class Leaf extends Component
{
/**
* Leaf constructor.
*/
public function __construct($name)
{
parent::__construct($name);
}
public function add(Component $c)
{
echo '不能添加' . PHP_EOL;
}
public function remove(Component $c)
{
echo '不能删除' . PHP_EOL;
}
public function display($depth)
{
echo str_repeat('-', $depth) . $this->name . PHP_EOL;
}
}
/**
* 定义有枝节点行为,用来存储子部件,在 Component 接口中实现与子部件有关的操作,
* 比如增加、删除
*
* Class Composite
*/
class Composite extends Component
{
/**
* @var Component[]
*/
private $list = [];
/**
* Composite constructor.
*/
public function __construct($name)
{
parent::__construct($name);
}
public function add(Component $c)
{
$this->list[] = $c;
}
public function remove(Component $c)
{
$key = array_search($c, $this->list);
if ($key !== false && array_key_exists($key, $this->list)) {
unset($this->list[$key]);
}
}
public function display($depth)
{
echo str_repeat('-', $depth) . $this->name . PHP_EOL;
foreach ($this->list as $children) {
$children->display($depth + 1);
}
}
}
$root = new Composite('root');
$root->add(new Leaf('leaf a'));
$root->add(new Leaf('left b'));
$comp = new Composite('x');
$comp->add(new Leaf('x a'));
$comp->add(new Leaf('x b'));
$root->add($comp);
$comp2 = new Composite('xy');
$comp2->add(new Leaf('xy a'));
$comp2->add(new Leaf('xy b'));
$root->add(new Leaf('leaf c'));
$leafd = new Leaf('leaf d');
$root->add($leafd);
$root->remove($leafd);
$root->add($comp2);
$root->display(0);