即使我写了这样的文章,我依然坚信设计模式只是某些垃圾语言用来规避其语言本身弊端的规范而已,不然,就只能写出糟糕的代码了。
创建型
Factory Method(工厂方法模式/工厂模式)
工厂模式是一种类,提供了创建对象的某些方法,可以直接使用工厂类创建对象,而不是直接使用new。
优点:如果要改变所创建对象的类型,只需要修改该工厂即可。比如有个类需要读取用户数据来创建,原本是读取的数据库,现在要从文本读取,就得把那个类及其所有依赖都更改一遍。
php示例
1 |
|
AbstractFactory(抽象工厂模式)
抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。客户端程序不需要知道(或关心)它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。
php示例,代码来自维基百科
1 |
|
Prototype(原型模式)
通过复制一个已经存在的实例来返回新的实例,而不是新建实例。
优点: 多用于创建复杂的或者耗时的实例,这种情况,复制一个已经存在的实例使程序运行更高效,活着创建值相等,只是命名不一样的同类数据。
Singleton(单例模式)
php示例,代码来自IBM
1 |
|
结构型
Adapter Class/Object(适配器/转换器)
介绍: 把一个类的接口变换成客户端所期待的另一种接口,Adapter模式使原本因接口不匹配或不兼容而无法在一起工作的两个类能够在一起工作。外部请求方式一样,内部实现方式不一样。
应用场景:
- 想使用一个已经存在的类,但是它的接口并不完全符合需求
- 适用于第三方库的API会发生改变而选择不直接把第三方API给用户使用的情况下,在前面封装一层。
php实例,代码来自真实的归宿
1 |
|
Bridge(桥接模式)
把事务对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。
python实例,代码来自维基百科
1 | """圆形、三角形归于抽象的形状,而画圆、画三角形归于抽象的画图""" |
Composite(组合模式)
Decorator(装饰模式)
Facade(外观)
Flywight(享元)
Proxy(代理)
行为型
Interpreter(解释器)
Template Method(模板方法)
Observer(观察者模式)
优点: 被观察对象不用具体了解观察者具体实现,而是由观察者去实现。被观察者忽略了依赖它的对象,它要关注在事件发生时触发该事件并发送消息给观察者即可。这个和依赖注入有点相近的地方。
php示例,代码来自IBM
1 |
|
Command(命令)
Chain of Respopnsibility(责任链)
包含了一些命令对象和一系列的处理对象,每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。
php示例,代码来自维基百科
1 |
|
Iterator(迭代器)
Mediator(中介者)
Memento(备忘录)
State(状态)
Strategy(策略模式)
指对象有某种行为,但是在不同的场景中,该行为有不同的实现算法。
抽象工厂与策略模式不同的地方在于,工厂是创建型模式,关注的是对象的创建,而策略是行为型模式,关注的是对行为的封装,对于工厂来说无论返回的对象内部是怎样的,只要是我想要的对象就行,而对于策略模式来说返回的对象即使不同也会有相同的方法/行为。
php示例,代码来自维基百科
1 |
|
Visitor(放问者)
TroubleShooting
工厂模式和策略模式的区别
如大多数网上的解释一样,工厂模式更注重对象的创建,策略模式更注重行为的不同。根据我的理解工厂模式更适用于创建不同的对象,这些对象拥有不同的方法。而策略模式则更多是针对有相同方法的对象。例如网上的文章经常举的例子一样,数据库的操作,其实每个数据库的操作都不一样,所以这里更适用于工厂模式。但是如果有后端一样的场景,那么策略模式就更方便了。例如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 工厂模式
DBFactory::create(Redis::class)->record()->add();
# 策略模式(不同的公有云相同的create方法)
abstract class CloudContext
{
protected $cloud;
public function __construct(Cloud $cloud) {
$this->cloud = $cloud;
}
}
class HostContext extends CLoudContext
{
public function create(
$this->cloud->create();
);
}
$host new HostContext(CloudFactory::create(AliyunCloud::class));
$host->create();