GoF23种软件设计模式
随着面向对象技术的发展和广泛应用,设计模式已经广泛的应用于面向对象系统的设计和开发,成为面向对象技术的一个重要组成部分。设计模式被定义为是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。程序员们使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。在我看来其实软件设计模式就是由前人所总结出来的在特定的情况下用来解决实际问题一套解决方案。
通常根据目的(即模式是用来做什么的)将23种设计模式分为3类:
- 创建型模式(用于创建对象):
工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)、原型模式(Prototype)和单例模式(Singleton)。
- 结构型模式(用于处理类或对象的组合):
适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)。
- 行为型模式(用于描述类或对象怎样交互和怎样分配职责):
职责链模式(Chain of Responsibility)、命令模式(Command)、解释器模式(Interpreter)、迭代器模式(Iterator)、中介者模式(Mediator)、备忘录模式(Memento)、观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、模板方法模式(Template Method)和访问者模式(Visitor)。
【创建型模式】:关注对象的创建过程,将对象的创建和使用分离,使用对象时无需知道对象创建细节,使得相同的创建过程可以多次复用。使整个系统的设计更加符合单一职责原则。
工厂方法模式
- 结构:抽象产品(Product)、具体产品(ConcreteProduct)、抽象工厂(Factory)、具体工厂(ConcreteProduct)。
- 定义:工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,将产品类的实例化操作延迟到工厂子类中完成,从而在一定程度上满足“开闭原则”。
- 适用环境:
a) 一个类不知道它说需要的对象的具体的类
b) 一个类通过其子类来指定创建哪个对象
c)将创建对象的任务委托给多个工厂子类中的某一个
抽象工厂模式
- 结构:抽象工厂(AbstractFactory)、具体工厂(ConcreteFactory)、抽象产品(AbstractProduct)、具体产品(ConcreteFactory)
- 定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 使用环境:
a) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
b) 系统中有多于一个的创建对象的工厂
c)属于同一个工厂的产品将在一起使用
d) 系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于具体实现。
建造者模式
- 结构:抽象建造者(Builder)、具体建造者(ConcreteBuilder)、产品角色(Product)、指挥者(Director)。
- 定义:该模式提供了一个统一的抽象的实现父类(抽象建造者),该父类只提供模块的抽象方法,具体的实现子类(具体建造者)就继承该类并用自己的方式实现父类中的方法,然后再由一个指挥者来指定采取哪种组合的方式。侧重于一步步构造一个复杂对象,返回一个完整对象。
- 适用环境:
a)需要生成的产品对象有复杂的内部结构,对象通常包含多个成员属性
b) 需要生成的对象属性相互依赖,需要指定其生成顺序
c) 对象的创建过程独立于创建该对象的类
d) 隔离复杂对象的创建和使用,使相同的创建过程创建出不同的对象
原型模式
- 结构:抽象原型类(Prototype)、具体原型类(ConcretePrototype)、客户类(Client)。
- 定义:提供一个抽象父类,父类中提供一个克隆方法,子类继承父类,并实现父类中的克隆方法。用原型实例指定创建对象的种类,并通过复制原型创建新的对象。
- 适用环境:
a) 创建新对象成本较大
b)系统需要保存对象的状态,同时对象状态变化很小
c)需要避免使用分层次的工厂类来创建对象,同时类的实例对象只有一个或很少的几个组合状态
单例模式
- 结构:单例角色(Singleton)
- 定义:定义一个单例类,设计构造函数为私有,内部实现只生成一个实例,同时提供一个静态的方法让客户可以使用这个唯一实例。
- 适用环境:
a) 系统只需要一个实例化对象
b) 客户调用类的单例只允许使用一个公共访问点
【结构型模式】:关注如何将现有类或现有对象组织在一起形成强大的结构,根据“合成复用原则”,大多使用关联关系来代替继承关系。
适配器模式
- 结构:目标抽象类(Target)、适配器类(Adapter)、适配器者(Adaptee)、客户类(Client)。
- 定义:使接口不兼容的类可以一起工作,在中间起到一个接口转换的工作。
- 适用环境:
a)系统需要使用现有的类,但现有类的接口不符合系统需要
b) 要建立一个可以重复工作的类,用于与一些彼此之间没有太大关联的一些类。
桥接模式
- 结构:抽象类(Abstraction)、扩充抽象类(RefinedAbstraction)、实现类接口(Implementor)、具体实现类(ConcreteImplementor)。
- 定义:将抽象与实现分离,两者都可以独立的变化,降低类与类之间的耦合,减少代码编写量。
- 适用环境:
a)一个类存在两个独立变化的维度
b)不希望使用继承或因为继承导致系统类个数增加的系统
组合模式
- 结构:抽象构件(Component)、叶子构件(Leaf)、容器构件(Composite)、客户类(Client)。
- 定义:组合多个对象用来描述整体与部分之间的关系。
- 适用环境:
a)需要表示一个对象整体或部分层次
b) 对象的结构时动态的且复杂程度不一样,但客户需要一致地处理它们
装饰模式
- 结构:抽象构件(Component)、具体构件(ConcreteComponent)、抽象装饰类(Decorator)、具体装饰类(ConcreteDecorator)
- 定义:通过为抽象装饰类添加具体的装饰内容实现动态的给一个对象增加一些额外的职责。
- 适用环境:
a)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
b)需要动态地给一个对象增加功能。
外观模式
- 结构:外观角色(Facade)、子系统角色(SubSystem)
- 定义:将一个系统中的各种方法统一封装到一个类中,通过此类的实现外界与系统的交互。
- 适用环境:
a) 当要为一个复杂子系统提供一个简单接口时
b) 客户程序与多个子系统之间存在很大依赖性
享元模式
- 结构:抽象享元类(Flyweight)、具体享元类(ConcreteFlyweight)、非共享具体享元类(UnsharedConcreteFlyweight)、享元工厂类(FlyweightFactory)。
- 定义:利用共享技术支持对象的复用。系统使用少量的对象。
- 适用环境:
a) 一个系统有大量相同或相似的对象
b) 对象大部分状态都可以外部化,可以将内部状态传入对象
代理模式
- 结构:抽象主题角色(Subject)、代理主题角色(Proxy)、真实主题角色(RealSubject)。
- 定义:给一个对象提供一个代理,通过代理对象访问另一个对象。
- 适用环境:远程代理、虚拟代理、Copy-on-Write代理等
【行为型模式】:关注对象之间的交互。
职责链模式
- 结构:抽象处理者(Handler)、具体处理者(ConcreteHandler)、客户类(Client)。
- 定义:避免请求的发送方和接受方耦合在一起,让多个对象都有可能接受请求
- 适用环境:
a) 有多个对象可以处理同一个请求
b)在不明确接受者的情况下,向多个对象中的一个提交一个请求
c) 可动态指定一组对象处理请求
命令模式
1.结构:抽象命令类(Command)、具体命令类(ConcreteCommand)、调用者(Invoker)、接受者(Receiver)、客户类(Client)
2.定义:将一个请求的实现、发起、响应的过程分别封装,降低了系统之间的耦合度。
3.适用环境:
a) 系统需要在不同的时间指定请求、将请求排队和执行请求。
b) 系统需要支持命令的撤销操作和恢复撤销操作
c) 系统需要将一组操作组合在一起,即支持宏命令
解释器模式
- 结构:抽象表达式(AbstractExpression)、终结符表达式(TerminalExpression)、非终结符表达式(NonterminalExpression)、环境类(Context)、客户类(Client)
- 定义:定义语言的文法,并建立一个解释器来解释语言中的句子。
- 适用环境:
a) 文法较为简单的
b)一些重复出现的问题可以用一种简单的语言来进行表达
迭代器模式
- 结构:抽象迭代器(Iterator)、具体迭代器(ConcreteIterator)、抽象聚合类(Aggregate)、具体聚合类(ConcreteAggregate)。
- 定义:提供一种方法来访问聚合对象、而不用暴露这个对象的内部表示,别名为游标。
- 适用环境:
a) 访问一个聚合对象的内容而无需暴露其内部表示
b) 需要为聚合对象提供多种遍历方式
c) 为遍历不同的组合结构提供一个统一的接口
中介者模式
- 结构:抽象中介者(Mediator)、具体中介者(ConcreteMediator)、抽象同事类(Colleague)、具体同事类(ConcreteColleague)。
- 定义:对象与对象之间的交互不直接进行,而是通过中介者来实现交互。中介者将对象之间的交互抽取出来,大大减少对象间的关系数量。
- 适用环境:
a) 系统中对象之间存在复杂的引用关系
b) 一个对象由于引入其他很多对象并且直接和这些对象通信,导致难以复用该对象。
备忘录模式
- 结构:原发器(Originator)、备忘录(Memento)、负责人(Caretaker)
- 定义:获取一个对象的内部状态,并在该对象之外保存该状态,这样可以在以后将对象恢复到原先保存的状态。
- 适用环境:
a)保存一个对象在某一个时刻的状态或部分状态
观察者模式
- 结构:目标(Subject)、具体目标(ConcreteSubject)、观察者(Observer)、具体观察者(ConcreteObserver)。
- 定义:多个对象依赖于一个目标对象,当该目标对象发生改变时,多个对象也会随之发生改变。
- 适用环境:
b) 一个抽象模型有两个方面,其中一个方面依赖与另一个方面。
c) 一个对象的改变导致其他一个或多个对象也发生改变
状态模式
- 结构:环境类(Context)、抽象状态类(State)、具体抽象类(ConcreteState).
- 定义:允许一个对象在其内部状态改变时而改变它的行为,使得对象看起来似乎修改了它的类。
- 适用环境:
a) 对象的行为依赖于它的状态并且可以根据它的状态改变而改变它的相关行为。
策略模式
- 结构:境类(Context)、抽象策略类(Strategy)、具体策略类(ConcreteStrategy)
- 定义:实现目的的方法有多种,将每一种方法封装成一个类,它们继承同一个父类,在需要时可以相互替换。
- 适用环境:
b) 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关数据结构。
模板方法模式
- 结构:抽象类(AbstractClass)、具体子类(ConcreteClass)
- 定义:不改变算法的结构就可以重定义该算法的某些特定步骤。
- 适用环境:
a)框架设计
b)单元测试JUnit的TestCase
访问者模式
- 结构:抽象访问者(Vistor)、具体访问者(ConcreteVisitor)、抽象元素(Element)、具体元素(ConcreteElement)。
- 定义:将一个对象中的每一个元素抽取出来,单独的作为一个类,并继承一个公共的父类,然后定义一个抽象的操作,提供对每一个元素的操作方法,在子类中实现具体的操作方法,这样就能在不改变元素类的前提下,通过添加新的操作方法子类实现对元素的新的操作。
- 适用环境:
a) 一个对象结构包含很多类型的对象,希望对这些对象实施一些依赖其具体类型的操作。
b)对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。