##Gang of Four(GOF)
可以翻译为四人帮,指得是四个人一起出了一本名为《Design Patterns - Elements of Reusable Object-Oriented Software》的书。书中介绍了设计模式的概念。
设计模式,主要讲的是可重用
,扩展性强
,优雅
的解决问题的方法。他不是一个数据结构。相比于领域相关的设计,设计模式更贴近于代码层面的设计。
感觉几乎所有的设计模式都离不开接口
和继承
这两个概念。
Design Patterns
基于GOF的设计模式可分为三部分,分别是Creational Patterns
,Structural Patterns
,Behavioral Patterns
。
如果你是初学者,请参考资料tutorialspoint。这里主要是我的笔记,记录了我的理解与想法。
设计模式主要追求的是重用性和拓展性。强行在这里扯运行效率就是耍流氓。
Creational Patterns
主要有以下几种:
- Factory Method
- Abstract Factory
- Singleton
- Builder
- Prototype
Factory Mehthod
工厂模式,提供创建Object的方法。可能会比较奇怪,创建的话直接用关键词new
不就可以了吗?
该方法就是想将new
操作封装起来。例如有很多种Shape
,比如Circle
或者Square
。我们可以通过如下代码创建:1
2Shape shape1 = shapeFactory.getShape("CIRCLE");
Shape shape3 = shapeFactory.getShape("SQUARE");
通过工厂模式,首先我们获得的是Shape
接口,并不清楚关于CIRCLE
的真正Object是如何创建的。该Object可能是CIRCLE
,也可能是MYCIRCLE
。
该模式的好处有两点:
- 封装了创建Object的方法,有更强的安全性
- 提高了代码的复用性。比如想将
CIRCLE
改成MYCIRCLE
,只需要修改工厂,不需要在整个项目中全局修改。
Abstract Factory
如果工厂模式是用来创建Object,那么抽象工厂就是用来创建不同的工厂。层级上高了一层,但是感觉换汤不换药。
Builder
该方法用于一步一步创建复杂的Object。我觉得最经典的例子就是Android中创建对话框的示例代码。我们先创建一个Builder,随后添加一系列属性,最后创建这个Object。
1 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
Prototype
核心思想就是创建缓存。当直接创建一个Object开销很大时,我们可以在工厂内存做一些缓存。用于快速创建Object。
例如,当创建Object需要读取数据库数据时,我们可以将部分数据缓存起来,那么当下一次创建时就不需要繁重的数据库读取操作了。
或者,我们可以缓存整个Object,后面通过clone
方法去创建新对象。
Structural Patterns
主要有以下几种
- Adapter
- Bridge
- Composite
- Decorator
- Facade
- Flyweight
- Proxy
感觉这类Design Pattern主要解决的是在已有架构上如何优雅的添加新功能。既要有可拓展性,又不需要过分修改原代码。
Adapter
Adapter 主要用于弥补两个接口不兼容的问题。最早是在Android里遇到的listview
的Adapter
。通常Adapter
要实现一系列接口,随后其他主类具备Adapter
的实例,随后按照具体情况调用Adapter
的接口实现。
感觉还是蛮抽象的,举个例子。当前有AudioPlayer
具有play
功能。如果想添加其他的play
功能,并且该功能已经被VLCPlayer
和MP4Player
实现。我们可以在AudioPlayer
和其他player之间加一个Adapter
。
Bridge
个人感觉这是目前最难理解的设计模式。桥接模式把事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。如下图,我们现在有一套Abstraction
,也叫具体对象
。然后又有一系列Implementor
,也可以称之为行为
。通过桥接模式我们可以让对象更灵活得具备不同的行为。
下面是一个更具体的例子,我们可以让Circle
(事物)具备不同的Color
(行为)
Composite
当我们对于一组Object相同对待时,可以用Composite设计模式。通常这些Object用树结构存储起来,并具备一定层级关系。
简单讲,当我们有很多有关联的节点并且只有遍历操作时,可以将他们存成树结构(Composite模式)。
感觉不常用。
Decorator
当我们想基于原来基础添加新功能,同时不想破坏原有结构时,可以用Decorator模式。
简单讲,就是在外面包一层,同时添加些新功能。要注意Decorator一定要继承原先的接口,保持接口一致。
Facade
隐藏框架的复杂细节,同时提供一些简单的接口。
Flyweight
核心思路就是减少不必要的实例创建,减少内存占用率并提高性能。通常是用hashmap实现。
感觉就是在获取一个实例时,检查是否有相同的,如果有直接返回,没有就创建。
和Prototype的本质区别是clone
方法的有无。
Proxy
一个类代表另一个类。同样是外包一层,但是这次不添加任何新功能,但要有原类的所有接口。感觉是最鸡肋的设计模式了。
感觉和代理服务器一样,能解决特定问题(比如翻墙),但是对效率没有任何提高。
Behavioral Patterns
- Command
- Interpreter
- Iterator
- Mediator
- Observer
- State
- Strategy
- Chain of Responsibility
- Visitor
- Template Method
- Memento
Command
要有以下几个元素:实体,指令,执行者。指令由执行者实施,并作用于实体。下面的例子就是由Broker
执行买卖Stock
的操作。
Interpreter
主要用来解释文本,去衡量特定情况是否发生。该模式可以用在SQL语言解析等。
Mediator
Mediator通常用于简化多个物体之间的信号传递。通常多个物体会共享一个类似EventBus的类,使用EventBus的静态方法共享信息。
下面是一个聊天室的例子。
State
在State模式中类的行为基于状态
而变化。简单说就是实体具备几个互斥的状态。
Strategy
在策略模式中,类行为或者算法可以在运行时动态更改。核心在于动态更改
。
Strategy
和 Interpreter
有相似的地方,因为解释
也算作一种策略
下面的例子中,我们可以动态修改计算策略(加或减)。
Chain of Responsibility
该设计模式讲究分工
原则。对于一个请求,创建一个链式的处理器,当一个处理器无法处理请求时,将该请求转发给另一个处理器。值得注意的是,这个链式处理器有层次关系,通常按照一定顺序链接起来。
下面例子是一个Logger,根据等级又可分为INFO
,DEBUG
,ERROR
来输出。类似Logcat
Visitor
访问者模式有以下两个功能:
- 可以将Object与算法分离
- 通过这种模式我们可以添加新功能但不需要修改原有结构
这个模式其实比较诡异,建议直接看这个链接
在链接的例子中,我们可以添加其他ComputerPart
,同时不需要修改原内容。
Template
有一个模板类具备一些抽象方法,而子类需要重写该方法以实现自己的功能。通常模板类要有一个非抽象的方法调用子类实现的具体方法。具体可以看下面的例子。
Memento
该模式可以将Object回滚到之前的状态。感觉没什么意思。