8000 complete chapter 19 · webphper/design-patterns-by-php@02c1951 · GitHub
[go: up one dir, main page]

Skip to content

Commit 02c1951

Browse files
committed
complete chapter 19
1 parent f82c934 commit 02c1951

File tree

4 files changed

+366
-1
lines changed

4 files changed

+366
-1
lines changed

chapter19.md

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,115 @@
11
### 第十九章 分公司 = 一部分 --- 组合模式
2+
```php
3+
<?php
24

5+
// component为组合中的对象接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的字部件。
6+
abstract class Component
7+
{
8+
protected $name;
9+
10+
function __construct($name)
11+
{
12+
$this->name = $name;
13+
}
14+
15+
//通常用add和remove方法来提供增加或移除树枝货树叶的功能
16+
abstract public function add(Component $c);
17+
abstract public function remove(Component $c);
18+
abstract public function display($depth);
19+
}
20+
21+
//leaf在组合中表示叶节点对象,叶节点对象没有子节点。
22+
class Leaf extends Component
23+
{
24+
// 由于叶子没有再增加分枝和树叶,所以add和remove方法实现它没有意义,
25+
// 但这样做可以消除叶节点和枝节点对象在抽象层次的区别,它们具有完全一致的接口
26+
public function add(Component $c)
27+
{
28+
echo "can not add to a leaf\n";
29+
}
30+
31+
public function remove(Component $c)
32+
{
33+
echo "can not remove to a leaf\n";
34+
}
35+
36+
// 叶节点的具体方法,此处是显示其名称和级别
37+
public function display($depth)
38+
{
39+
echo str_repeat('-', $depth).$this->name."\n";
40+
}
41+
}
42+
43+
//composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加add和删除remove.
44+
45+
class Composite extends Component
46+
{
47+
//一个子对象集合用来存储其下属的枝节点和叶节点。
48+
private $childern = [];
49+
50+
public function add(Component $c)
51+
{
52+
array_push($this->childern, $c);
53+
}
54+
55+
public function remove(Component $c)
56+
{
57+
foreach ($this->childern as $key => $value) {
58+
if ($c === $value) {
59+
unset($this->childern[$key]);
60+
}
61+
}
62+
}
63+
64+
// 显示其枝节点名称,并对其下级进行遍历
65+
public function display($depth)
66+
{
67+
echo str_repeat('-', $depth).$this->name."\n";
68+
foreach ($this->childern as $component) {
69+
$component->display($depth + 2);
70+
}
71+
}
72+
}
73+
74+
//客户端代码
75+
76+
$root = new Composite('root');
77+
$root->add(new Leaf("Leaf A"));
78+
$root->add(new Leaf("Leaf B"));
79+
80+
$comp = new Composite("Composite X");
81+
$comp->add(new Leaf("Leaf XA"));
82+
$comp->add(new Leaf("Leaf XB"));
83+
84+
$root->add($comp);
85+
86+
$comp2 = new Composite("Composite X");
87+
$comp2->add(new Leaf("Leaf XA"));
88+
$comp2->add(new Leaf("Leaf XB"));
89+
90+
$comp->add($comp2);
91+
92+
$root->add(new Leaf("Leaf C"));
93+
94+
$leaf = new Leaf("Leaf D");
95+
$root->add($leaf);
96+
$root->remove($leaf);
97+
98+
$root->display(1);
99+
```
3100

4101
总结:
5102

103+
> ***组合模式***,将对象组合成树形结构以表示‘部分与整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
104+
105+
> 透明方式,子类的所有接口一致,虽然有些接口没有用。
106+
107+
> 安全方式,子类接口不一致,只实现特定的接口,但是这样就要做相应的判断,带来了不便。
108+
109+
> 需求中是体现部分与整体层次的结构时,或希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。
110+
111+
> 组合模式可以让客户一致地使用组合结构和单个对象。
6112
7113
上一章:[第十八章 如果再回到从前 --- 备忘录模式](https://github.com/flyingalex/design-patterns-by-php/blob/master/chapter18.md)
8114

9-
下一章:[第二十章](https://github.com/flyingalex/design-patterns-by-php/blob/master/chapter20.md)
115+
下一章:[第二十章 想走?可以!先买票 --- 迭代器模式](https://github.com/flyingalex/design-patterns-by-php/blob/master/chapter20.md)

chapter20.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### 第二十章 想走?可以!先买票 --- 迭代器模式
2+
3+
总结:
4+
5+
6+
7+
上一章:[第十九章 分公司 = 一部分 --- 组合模式](https://github.com/flyingalex/design-patterns-by-php/blob/master/chapter19.md)
8+
9+
下一章:[第二十章](https://github.com/flyingalex/design-patterns-by-php/blob/master/chapter21.md)

codes/Composite.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
// component为组合中的对象接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的字部件。
4+
abstract class Component
5+
{
6+
protected $name;
7+
8+
function __construct($name)
9+
{
10+
$this->name = $name;
11+
}
12+
13+
//通常用add和remove方法来提供增加或移除树枝货树叶的功能
14+
abstract public function add(Component $c);
15+
abstract public function remove(Component $c);
16+
abstract public function display($depth);
17+
}
18+
19+
//leaf在组合中表示叶节点对象,叶节点对象没有子节点。
20+
class Leaf extends Component
21+
{
22+
// 由于叶子没有再增加分枝和树叶,所以add和remove方法实现它没有意义,
23+
// 但这样做可以消除叶节点和枝节点对象在抽象层次的区别,它们具有完全一致的接口
24+
public function add(Component $c)
25+
{
26+
echo "can not add to a leaf\n";
27+
}
28+
29+
public function remove(Component $c)
30+
{
31+
echo "can not remove to a leaf\n";
32+
}
33+
34+
// 叶节点的具体方法,此处是显示其名称和级别
35+
public function display($depth)
36+
{
37+
echo str_repeat('-', $depth).$this->name."\n";
38+
}
39+
}
40+
41+
//composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加add和删除remove.
42+
43+
class Composite extends Component
44+
{
45+
//一个子对象集合用来存储其下属的枝节点和叶节点。
46+
private $childern = [];
47+
48+
public function add(Component $c)
49+
{
50+
array_push($this->childern, $c);
51+
}
52+
53+
public function remove(Component $c)
54+
{
55+
foreach ($this->childern as $key => $value) {
56+
if ($c === $value) {
57+
unset($this->childern[$key]);
58+
}
59+
}
60+
}
61+
62+
// 显示其枝节点名称,并对其下级进行遍历
63+
public function display($depth)
64+
{
65+
echo str_repeat('-', $depth).$this->name."\n";
66+
foreach ($this->childern as $component) {
67+
$component->display($depth + 2);
68+
}
69+
}
70+
}
71+
72+
//客户端代码
73+
74+
$root = new Composite('root');
75+
$root->add(new Leaf("Leaf A"));
76+
$root->add(new Leaf("Leaf B"));
77+
78+
$comp = new Composite("Composite X");
79+
$comp->add(new Leaf("Leaf XA"));
80+
$comp->add(new Leaf("Leaf XB"));
81+
82+
$root->add($comp);
83+
84+
$comp2 = new Composite("Composite X");
85+
$comp2->add(new Leaf("Leaf XA"));
86+
$comp2->add(new Leaf("Leaf XB"));
87+
88+
$comp->add($comp2);
89+
90+
$root->add(new Leaf("Leaf C"));
91+
92+
$leaf = new Leaf("Leaf D");
93+
$root->add($leaf);
94+
$root->remove($leaf);
95+
96+
$root->display(1);
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+

codes/CompositeCompany.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
// 公司管理系统
4+
//公司抽象类
5+
abstract class Company
6+
{
7+
protected $name;
8+
function __construct($name)
9+
{
10+
$this->name = $name;
11+
}
12+
13+
abstract public function add(Company $c);
14+
abstract public function remove(Company $c);
15+
abstract public function display($depth);
16+
abstract public function lineOfDuty();//职责,不同部门需要履行不同的职责
17+
}
18+
19+
//具体公司类,实现接口 树枝节点
20+
class ConcreteCompany extends Company
21+
{
22+
private $childern = [];
23+
public function add(Company $c)
24+
{
25+
array_push($this->childern, $c);
26+
}
27+
28+
public function remove(Company $c)
29+
{
30+
foreach ($this->childern as $key => $value) {
31+
if ($c === $value) {
32+
unset($this->childern[$key]);
33+
}
34+
}
35+
}
36+
37+
// 显示其枝节点名称,并对其下级进行遍历
38+
public function display($depth)
39+
{
40+
echo str_repeat('-', $depth).$this->name."\n";
41+
foreach ($this->childern as $component) {
42+
$component->display($depth + 2);
43+
}
44+
}
45+
46+
public function lineOfDuty()
47+
{
48+
foreach ($this->childern as $company) {
49+
$company->lineOfDuty();
50+
}
51+
}
52+
}
53+
54+
55+
//人力资源部
56+
class HRDepartment extends Company
57+
{
58+
public function add(Company $c){}
59+
60+
public function remove(Company $c){}
61+
62+
// 显示其枝节点名称,并对其下级进行遍历
63+
public function display($depth)
64+
{
65+
echo str_repeat('-', $depth).$this->name."\n";
66+
}
67+
public function lineOfDuty()
68+
{
69+
echo $this->name."-----员工招聘培训\n";
70+
}
71+
}
72+
73+
//财务部
74+
class FinanceDepartment extends Company
75+
{
76+
public function add(Company $ 10000 c){}
77+
78+
public function remove(Company $c){}
79+
80+
// 显示其枝节点名称,并对其下级进行遍历
81+
public function display($depth)
82+
{
83+
echo str_repeat('-', $depth).$this->name."\n";
84+
}
85+
public function lineOfDuty()
86+
{
87+
echo $this->name."-----公司财务收支管理\n";
88+
}
89+
}
90+
91+
$root = new ConcreteCompany("北京总公司");
92+
$root->add(new HRDepartment("北京人力资源部"));
93+
$root->add(new FinanceDepartment("北京财务部"));
94+
95+
96+
$comp = new ConcreteCompany("上海分公司");
97+
$comp->add(new HRDepartment("上海人力资源部"));
98+
$comp->add(new FinanceDepartment("上海财务部"));
99+
$root->add($comp);
100+
101+
$comp1 = new ConcreteCompany("南京分公司");
102+
$comp1->add(new HRDepartment("南京人力资源部"));
103+
$comp1->add(new FinanceDepartment("南京财务部"));
104+
$comp->add($comp1);
105+
106+
$comp2 = new ConcreteCompany("杭州分公司");
107+
$comp2->add(new HRDepartment("杭州人力资源部"));
108+
$comp2->add(new FinanceDepartment("杭州财务部"));
109+
$comp->add($comp2);
110+
111+
echo "结构图:\n";
112+
$root->display(1);
113+
114+
echo "\n职责:\n";
115+
$root->lineOfDuty();
116+
117+
118+
119+
120+
121+
122+
123+
124+
125+
126+
127+
128+

0 commit comments

Comments
 (0)
0