神的尾巴

全栈工程师、独立开发者

0%

聊聊设计模式-结构型

纯手写,可能有错误,欢迎指出

适配器模式

抽象目标接口,使用适配器实现抽象目标接口,适配器有对象适配器和类适配器(实际一个使用组合一个使用继承)

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
// 目标类
interface Target {
public function request();
}

class LocalLogic {
public function localRequset()
{
// ...
}
}

// 1. 对象适配器(推荐)
class Adapter implements Target
{
private $localLogic;
public function __construct($localLogic)
{
$this->localLogic = $localLogic;
}
public function request()
{
return $this->localLogic->localRequest();
}
}

// 2. 类适配器
class Adapter extends LocalLogic implements Target
{
public function request()
{
return $this->localRequest();
}
}

桥接模式

相对于是适配器模式,两边都是需要变化的,两边都需要进行抽象处理。

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
// 组合Implementor的抽象类
abstruct class Abstraction
{
private $imp;
public function __construct($imp)
{
$this->imp = $imp;
}
public function operation()
{
$this->imp->run();
}
}

// Abstraction的实现类
class RefinedAbstraction extends Abstraction
{
public function __construct($imp)
{
parent::__construct($imp);
}

public function operation()
{
parent->operation();
$this->imp->run();
// ...
}
}

// Implementor接口
interface Implementor
{
public function run();
}

// Implementor实现类
class ImplementorA implements Implementor
{
public function run()
{
// ...
}
}

组合模式

比较适合用在层级结构,在层级结构中包含容器节点和叶子节点,容器节点又可以包含叶子节点,比较适合用于文件系统。

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
// 文件抽象类,因为包含属性name,没使用接口
abstract class File
{
private $name;
public function __construct($name) {
$this->name = $name;
}
abstract public function display();
}

// 文本文件,叶子节点
class TextFile extends File
{
public function __construct($name) {
parent::__construct($name);
}
public function display()
{
// ...
}
}

// 文件夹,容器节点
class Folder extends File
{
private $files;
public function __construct($name)
{
parent::__construct($name);
$files = []; // 包括容器节点和叶子节点
}
public function add($file)
{
$files[] = $file;
}
public function remove($file)
{
$fileKey = array_search($file,$files);
if($fileKey !== false){
unset($files[$fileKey]);
}
}
public function display()
{
// ...
}
}

装饰器模式

装饰模式使用组合加抽象给一个对象进行扩展,而不用添加多个子类。

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
// 组件接口
interface Component
{
public function operation();
}

// 组件实现类
class ComponentA implements Component
{
public function operation()
{
// ...
}
}

// 装饰器抽象类
abstract class Decorator implements Component
{
protected $component;
// 传入组件实现类进行包装
public function __construct($component)
{
$this->component = $component;
}
public function operation()
{
return $this->component->operation();
}
}

// 装饰器实现类A
class DecoratorA extends Decorator
{
private function otherOperation()
{
// ...
}
public function operation()
{
parent::operation();
$this->otherOperation();
}
}

外观模式

用来包装子系统的一组接口,定义一个高层接口。

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
// 外观类
class Facada
{
private $subSystemA;
private $subSystemB;
private $subSystemC;
public function __construct()
{
$this->subSystemA = new SubSystemA();
$this->subSystemB = new SubSystemB();
$this->subSystemC = new SubSystemC();
}
public function run()
{
$this->subSystemA->doA();
$this->subSystemB->doB();
$this->subSystemC->doC();
}
}

// 子系统类A
class SubSystemA
{
public function doA()
{
// ...
}
}

// 子系统类B
class SubSystemB
{
public function doB()
{
// ...
}
}

// 子系统类C
class SubSystemC
{
public function doC()
{
// ...
}
}

享元模式

其实享元模式和单例比较类似,但是享元模式有多个实例,多个变量对应一个实例,有利于节约内存空间,提高系统性能。

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
// 享元接口
interface Flyweight
{
public function operation();
}

// 享元对象
class ConcreteFlyweight implements Flyweight
{
private $intrinsicState ;
public function __construct($intrinsicState)
{
$this->intrinsicState = $intrinsicState;
}
public function operation()
{
// ...
}
}

// 享元工厂
class FlyweightFactory
{
private $instances;
public function __construct()
{
$this->instances = [];
}
public function getFlyweight($intrinsicState)
{
if(!isset($this->instances[$intrinsicState])) {
$this->instances[$intrinsicState] = new CroncreteFlyweight($intrinsicState);
}
return $this->instances[$intrinsicState];
}
}

代理模式

通过代理对象间接访问一个对象,起到中介的作用

这里简单说下代理模式,适配器模式和装饰器模式的区别:

  1. 代理模式和装饰器模式都是实现目标接口,而适配器模式,只有适配器实现目标接口(对象适配器)
  2. 代理模式隐藏原类,装饰器模式则以对客户端透明方式扩展对象(用来替代继承)
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
// 目标接口
interface Target
{
public function request();
}

// 真实对象
class RealTarget implements Target
{
public function request()
{
// ...
}
}

// 代理对象
class Proxy implements Target
{
private $realTarget;
public function __construct($realTarget)
{
$this->realTarget = $realTarget;
}
private function preRequest()
{
// ...
}
private function afterRequest()
{
// ...
}
public function request()
{
$this->preRequest();
$this->realTarget->request();
$this->afterRequset();
}
}
觉得对你有帮助的话,请我喝杯咖啡吧~.