设计模式是一个比较抽象的编程思想,有必要再强调一遍的是,设计模式是一种思想,你在实际的产品中看到的代码未必能和设计模式的思想完全吻合,但你能瞥见一些设计模式的血脉在其中延续,反之亦然,完全按设计模式写的代码也未必能用到实际的产品中,还需要根据业务逻辑加一些各种各样的东西。
总之,设计模式是抽象的,网络上、书籍中,大部分讲设计模式的文章都很难给出一个在实际场景中显露了设计模式思想的完整的代码,因为这种代码要么很长,要么涉及面很广,不容易扒拉下来。
在这篇文章里,我们将基于TypeScript(以下简称TS),对设计模式做一个速通。
首先,设计模式(Design patterns)被普遍认为有三大类(5+7+10=22种):
- Creational Patterns
- Abstract Factory
- Builder
- Factory Method
- Prototype
- Singleton
- Structural Patterns
- Adapter
- Bridge
- Composite
- Decorator
- Facade
- Flyweight
- Proxy
- Behavioral Patterns
- Chain of Responsibility
- Command
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
正如本文开头所强调的,设计模式是一种思想,他可能并不能直接变成一个业务解决方案,比如直接变成一个具备xx功能的表单,但你的代码中总会显露出设计模式的脉络。例如Behavioral Patterns中的Iterator,他的基本实现就是写一个迭代器
interface Iterator<T> {
// Return the current element.
current(): T;
// Return the current element and move forward to next element.
next(): T;
// Return the key of the current element.
key(): number;
// Checks if current position is valid.
valid(): boolean;
// Rewind the Iterator to the first element.
rewind(): void;
}
我们肯定在代码中用了迭代器,但可能我们并没有自己实现,并且可能没意识到这是一种设计模式。
根据设计模式的流行度,本文挑一些常见的设计模式进行讲解(流行度来自refactoring.guru)
创建型模式(Creational Patterns)系列
创建型模式中,比较容易理解的应该是工厂模式Factory Method,例如构建UI时,可能使用过的create_button\create_checkbox这样的方法
工厂模式本身是容易理解的,他的进阶包括Abstract Factory、Builder、Prototype
Abstract Factory可以用来构建跨平台UI,比如我们设计了一个抽象GUI工厂接口,继承这个接口实现了Win工厂和Mac工厂,我们的app读入GUI工厂类,这样我们只需要更改给app传入的是Win工厂还是Mac工厂就可以实现跨平台UI了
Builder则适合用在一些需要自定义的场景,比如我们预先设计了一个按钮builder,通过控制这个builder的一些参数或者方法,我们可以生产不同的button,那我们就可以再设计一个director类,这个类中写了生产不同button的方法,通过director我们就可以方便地生成不同button了
Prototype主要特点是原型接口提供了clone方法,通过原型生成的对象可以方便地复制,因为总有一些场合,从外部去复制一个对象非常麻烦(遍历大量属性或者不知道确切的类型)
此外,还有一个Singleton,这个模式非常容易理解,一个类下面只允许一个实例存在,一般用于config,某些抽象类既可以是工厂也可以是Singleton,因为Singleton是非常自由的
结构模式(Structural Patterns)系列
这系列中常见的是Adapter,也叫Wrapper,应用场景例如,在一个业务中,上游传来的是XML格式,下游需要的是JSON格式,这时候就可以写一个Adapter,它有一个属性adaptee,类型是下游服务,在Adapter中写一个转XML为JSON的方法,就可以给下游服务调用了
行为模式(Behavioral Patterns)系列
这系列中常见的包括command、observer
command又叫action/transaction,核心思想是把各种功能(保存、删除、复制)写成命令,以便于复用。例如一个编写GUI的场景,用户可以通过按钮、菜单、快捷键去复制文本,复制文本的代码可能要到处重复,但通过在GUI和业务逻辑中加一个命令层,这些重复的代码就可以大大减少
observer又叫Event-Subscriber、Listener,各种listener就是他的最佳实践,在此不再赘述
其实设计模式和OOP(Object-Oriented Programming)有着密切连续,比如工厂模式就非常依赖接口、继承的思想,随着如今ts中函数式编程的火热,设计模式可能也变得不再那么明显,但我们依然可以从这些智慧思想中发掘出对自己有益的部分