设计模式
设计模式概述
在20世纪70年代,Christopher Alexander 提出了城市建筑的模式,他认为:模式是描述一个不断发生的问题和该问题的解决方案。随后,Erich Gamma,Richard Helm,Ralph Johnson 和John Vlissides 写了一本著名的参考书《设计模式:可复用面向对象软件的基础》,后人也因为这本书称四人为四人组,将这本书中描述的模式称为GoF(Gang of Four)设计模式。在这本书中,四人组将设计模式定义为:对被用来在特定场景下解决一般设计问题的类和互相通信的对象的描述。通俗的说,可以把设计模式理解为对某一类问题的通用解决方案。
设计模式的概念
首先,设计模式解决的是一类问题,例如工厂模式就是为了解决类的创建的问题,而适配器模式则是为了解决类接口不匹配的问题。如果把解决A问题的设计模式用于B问题,结果肯定张冠李戴。所以在描述设计模式前,首先要描述这个设计模式究竟要研究什么样的问题。
其次,设计模式是一种通用的解决方案,而不是具体的。也不是唯一的。在GoF的书中对设计的描述着重于思想的描述,虽然也给出了C++的实现方法。但同样也可以用Java甚至面向对象的语言实现。具体应用时可以根据实际情况进行相应的变化。
设计模式的组成
一般的,在描述一个设计模式时,至少需要包含四个方面:模式名(Pattern name),问题(problem),解决方案(solution),效果(consequence)。这四个方面是设计模式的四要素。名不正言不顺,每种设计模式都有自己的名字,也就是模式名;设计模式都有其应用的场合,即该设计模式意图解决的问题,超出了这个问题就不应该再应用这种模式,所以问题是设计模式的第二要素;设计模式的目的既是解决问题,所以在描述设计模式时当然要有解决问题的方法描述,这就是设计模式的另一要素--解决方案;对于每一种设计模式而言,还有其更具体的效果描述,所以设计模式的最后一个要素就是效果。
23种设计模式
- Factory Method 模式(工厂模式)。Factory Method模式提供了一种延迟创建类的方法,使用这个方法可以在运行期由子类决定创建哪一种类的实例。
- Abstract Factory模式。Abstract Factory又称为工厂模式,该模式主要为解决复杂系统中对象创建的问题。抽象工厂模式提供了一个一致的对象创建接口来创建一系列具有相似基类或相似接口的对象。
- Builder模式(建造者模式)。Builder模式与Abstruct Factory模式非常类似,但是Builder模式是逐步的构造出一个复杂对象。并在最后返回对象的实例。Builder模式可以把复杂对象的创建与表示分离。
- Prototype模式(原型模式)。Prototype模式可以根据原型实例制定创建的对象的种类,并通过深复制这个原型来创建新的对象。Prototype模式有着同Abstract Factory模式和Builder模式相同的效果。不过当小实例化的类是运行期才被指定的而且要避免创建一个与产品曾是平行的工厂类层次时,可以使用Prototype模式,使用Prototype模式可以在运行时增加或减少原型,比Abstract Fac和Builder模式更加灵活。
- Singleton模式(单例模式)。Singleton模式也是一种很有代表性的模式,使用Singleton模式可以保证一个类仅有一个实例。从而可以提供一个单一的全局访问点。
- Adapter模式(适配器模式)。Adapter模式而言解决系统间接口不相容的问题,通过Adapter可以把类的接口转化为客户程序所希望的接口,从而提高复用性。
- Bridge模式(桥接模式)。Bridge模式把类的抽象部分和实现部分分离,这样类的抽象和实现都可以独立变化。
- Composite模式(组合模式)。composite模式提供了一种以树形结构组合对象的方法。使用Composite可以使单个对象和组合后的对象具有一致性,以提高软件的复用性。
- Decorator模式(装饰器模式)。Decorator模式可以动态的为对象的某一种方法增加更多的功能呢,在很多时候,使用Decorator模式可以不必继承出新的子类从而维护简介的类继承结构。
- Facade模式 (外观模式)。Facade模式为一组类提供了一致的访问接口。使用Facade可以封装nebula具有不同接口的类。是其对外提供统一的访问接口。
- Flyweight模式(享元模式)。Flyweight模式可以共享大量的细粒度对象。从而节省创建对象所需要分配的空间。不过在时间上的开销会变大。
- Proxy模式(代理模式)。顾名思义,Proxy模式为对象提供了一种访问代理。通过对象Proxy可以控制客户程序的访问。例如:访问权限的控制,访问地址的控制,访问方式的控制等。甚至可以通过Proxy将开销较大的访问化整为零,提高访问效率。
- Interpreter模式(解释器模式)。定义了一个解释器。来解释遵循给定语言和文法的句子。
- Template Method模式(模板方法模式)。定义一个操作的模板,其中的一些步骤会在子类中实现,以适应不同的情况。
- Chain of Responsibility模式(责任链模式)。Chain of Responsibility模式把可以相应请求的对象组织成一条链。并在这条对象链上传递请求。从而保证多个对象都有机会处理请求而且可以避免请求方和响应方的耦合。
- Command模式(命令模式)。将请求封装为对象。从而增强请求的能力。如参数化,排队,记录日志等。
- Iterator模式。Iterator模式提供了顺序访问一个对象集合中各元素的方法,使用Iterator可以避免暴露集合中对象的耦合关系。
- Mediator模式(中介者)。Mediator模式可以减少系统中对象间的耦合性。Mediator模式使用中介对象封装其他对象。从而使这些被封装的对象间的关系称为松耦合。
- Memento模式(备忘录模式)。Memento模式提供了一种捕获对象状态的方法。而且不会破坏对象的封装。并且可以在对象外部保存对象的状态。并在需要的时候回复对象状态。
- Observer模式(观察者模式)。Observer模式提供了将对象的状态广播到一组观察者的方式。从而可以让每个观察者随时可以得到对象更新的通知。
- State模式(状态模式)。State模式允许一个对象在其内部状态改变的时候改变他的行为。
- Strategy模式(策略模式)。使用Strategy模式可以让对象中算法的变化独立于客户。
- Visitor模式(访问者模式)。表示对某对象结构中各元素的操作。使用Visitor模式可以在不改变各元素类的前提下定义作用于这些元素的新操作。
设计模式与软件架构
很多时候大家说起架构就提设计模式,说设计模式就说架构师。搞得玄之又玄的。一些混子挂着架构师的名头,其实只是把前人留下的架构搞熟悉了,再熟悉业务流程,就招摇撞骗了,很多基础的东西都不懂,为什么这么设计懂,为什么选这个结构不懂,架构有没有问题不懂(提到这里,就忍不住吐槽以前遇到的一些混子)。
这里直接说一下架构和设计模式的区别。软件架构描述的是软件的组成。如果做架构设计,如何描述架构。会用到例如经典的"4+1"视图,将软件架构通过逻辑视图,开发视图,进程视图,物理视图和场景视图来进行面so。在这些视图中,描述软件系统中类之间的关系,进程之间的关键,软件和硬件的结合等问题。一般来说软件架构更倾向于从整体和全局上描述软件的组成。
而设计模式则更侧重于类与类,对象与对象之间的关系。例如逻辑视图中,可以使用多种设计模式来组织类与类之间的关系。因此,设计模式和软件架构是面向不同层次问题的解决方案。
同设计模式一样,软件架构也有一些固定的模式,通常称为架构风格。常见的架构风格有分层架构,客户端-服务器架构,消息总线,面向服务的架构(SOA)等。
软件架构风格同设计模式在某种含义上市一致的。设计模式和软件架构中蕴含的很多思想是一致的。无论是架构风格还是设计模式,人们在追求良好设计的过程中,将一些常见解决方案总结,整理出来,形成固定的风格与模式。例如消息总线的架构风格同Observer模式就有相似之处。因此,掌握设计模式对于软件架构设计有很大的帮助。但是只懂设计模式。并不一定能做好架构。
设计模式分类
设计模式是面向问题的,每一种设计模式都是为了解决一种特定类型的问题。因此,根据设计模式要解决的问题,将设计模式分为三类。分别为 创建型,结构型,和行为型 。
事实上,面向对象的设计中,需要解决的就是:如何管理系统中的对象,如何组织系统中的类与对象,系统中类与对象如何相互通信。这三类设计模式分别解决了这三个方面的问题。
创建型设计模式
主要解决对象的创建的问题,在最简单的情况下,在程序中定义 类,在使用时创建一个对象实例。但在实际开发中,对象的创建会变得复杂很多,这时候需要使用创建型设计模式解决创建对象的问题。
结构型设计模式
随着开发系统的不断扩张,系统功能更加丰富,墨迹间的附庸越来越多,系统中类与对象的结构变得更加复杂。如果缺乏良好的设计,这些类之间的额关系将会变得非常混乱。结构型设计模式就是为了解决这些问题的。
行为型设计模式
,行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。