设计模式

主要介绍了GOF系列的设计模式

##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
2
Shape shape1 = shapeFactory.getShape("CIRCLE");
Shape shape3 = shapeFactory.getShape("SQUARE");

通过工厂模式,首先我们获得的是Shape接口,并不清楚关于CIRCLE的真正Object是如何创建的。该Object可能是CIRCLE,也可能是MYCIRCLE

该模式的好处有两点:

  1. 封装了创建Object的方法,有更强的安全性
  2. 提高了代码的复用性。比如想将CIRCLE改成MYCIRCLE,只需要修改工厂,不需要在整个项目中全局修改。
factory-method.jpg

Abstract Factory

如果工厂模式是用来创建Object,那么抽象工厂就是用来创建不同的工厂。层级上高了一层,但是感觉换汤不换药。

abstract-factory.jpg

Builder

该方法用于一步一步创建复杂的Object。我觉得最经典的例子就是Android中创建对话框的示例代码。我们先创建一个Builder,随后添加一系列属性,最后创建这个Object。

1
2
3
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Hello").setTitle("Title");
Dialog dialog = builder.create();

Prototype

核心思想就是创建缓存。当直接创建一个Object开销很大时,我们可以在工厂内存做一些缓存。用于快速创建Object。

例如,当创建Object需要读取数据库数据时,我们可以将部分数据缓存起来,那么当下一次创建时就不需要繁重的数据库读取操作了。

或者,我们可以缓存整个Object,后面通过clone方法去创建新对象。

Structural Patterns

主要有以下几种

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy

感觉这类Design Pattern主要解决的是在已有架构上如何优雅的添加新功能。既要有可拓展性,又不需要过分修改原代码。

Adapter

Adapter 主要用于弥补两个接口不兼容的问题。最早是在Android里遇到的listviewAdapter。通常Adapter要实现一系列接口,随后其他主类具备Adapter的实例,随后按照具体情况调用Adapter的接口实现。

感觉还是蛮抽象的,举个例子。当前有AudioPlayer具有play功能。如果想添加其他的play功能,并且该功能已经被VLCPlayerMP4Player实现。我们可以在AudioPlayer和其他player之间加一个Adapter

adapter.jpg

Bridge

个人感觉这是目前最难理解的设计模式。桥接模式把事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。如下图,我们现在有一套Abstraction,也叫具体对象。然后又有一系列Implementor,也可以称之为行为。通过桥接模式我们可以让对象更灵活得具备不同的行为。

bridge-1.jpg

下面是一个更具体的例子,我们可以让Circle(事物)具备不同的Color(行为)

bridge-2.jpg

Composite

当我们对于一组Object相同对待时,可以用Composite设计模式。通常这些Object用树结构存储起来,并具备一定层级关系。

简单讲,当我们有很多有关联的节点并且只有遍历操作时,可以将他们存成树结构(Composite模式)。

感觉不常用。

composite.jpg

Decorator

当我们想基于原来基础添加新功能,同时不想破坏原有结构时,可以用Decorator模式。

简单讲,就是在外面包一层,同时添加些新功能。要注意Decorator一定要继承原先的接口,保持接口一致。

decorator.jpg

Facade

隐藏框架的复杂细节,同时提供一些简单的接口。

Flyweight

核心思路就是减少不必要的实例创建,减少内存占用率并提高性能。通常是用hashmap实现。

感觉就是在获取一个实例时,检查是否有相同的,如果有直接返回,没有就创建。

和Prototype的本质区别是clone方法的有无。

flyweight.jpg

Proxy

一个类代表另一个类。同样是外包一层,但是这次不添加任何新功能,但要有原类的所有接口。感觉是最鸡肋的设计模式了。

感觉和代理服务器一样,能解决特定问题(比如翻墙),但是对效率没有任何提高。

Behavioral Patterns

  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Observer
  • State
  • Strategy
  • Chain of Responsibility
  • Visitor
  • Template Method
  • Memento

Command

要有以下几个元素:实体,指令,执行者。指令由执行者实施,并作用于实体。下面的例子就是由Broker执行买卖Stock的操作。

command.jpg

Interpreter

主要用来解释文本,去衡量特定情况是否发生。该模式可以用在SQL语言解析等。

interpreter.jpg

Mediator

Mediator通常用于简化多个物体之间的信号传递。通常多个物体会共享一个类似EventBus的类,使用EventBus的静态方法共享信息。

下面是一个聊天室的例子。

mediator.jpg

State

在State模式中类的行为基于状态而变化。简单说就是实体具备几个互斥的状态。

state.jpg

Strategy

在策略模式中,类行为或者算法可以在运行时动态更改。核心在于动态更改

StrategyInterpreter 有相似的地方,因为解释也算作一种策略

下面的例子中,我们可以动态修改计算策略(加或减)。
strategy.jpg

Chain of Responsibility

该设计模式讲究分工原则。对于一个请求,创建一个链式的处理器,当一个处理器无法处理请求时,将该请求转发给另一个处理器。值得注意的是,这个链式处理器有层次关系,通常按照一定顺序链接起来。

下面例子是一个Logger,根据等级又可分为INFO,DEBUG,ERROR来输出。类似Logcat
chain.jpg

Visitor

访问者模式有以下两个功能:

  1. 可以将Object与算法分离
  2. 通过这种模式我们可以添加新功能但不需要修改原有结构

这个模式其实比较诡异,建议直接看这个链接

在链接的例子中,我们可以添加其他ComputerPart,同时不需要修改原内容。

Template

有一个模板类具备一些抽象方法,而子类需要重写该方法以实现自己的功能。通常模板类要有一个非抽象的方法调用子类实现的具体方法。具体可以看下面的例子。

template-1.jpg template-2.jpg

Memento

该模式可以将Object回滚到之前的状态。感觉没什么意思。