以上就是我通过《大话设计模式》这本书中了解到的设计模式,它们都是前人们总结出来的经验,是一些常见问题的解决方案,而且能避免很多问题的发生,设计模式会用到单一职责原则,开放-封闭原则,依赖倒转原则,迪米特法则等
原则:
- 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因
- 开放-封闭原则:软件试题(类,模块,函数等)应该可以扩展但不能修改,可以说对于扩展是开放的,对于更改是封闭的
- 依赖倒转原则:高层模块不应该依赖低层模块.两个都应该依赖抽象;抽象不应该依赖细节.细节应该依赖抽象
这么多设计模式大家可能会看的眼花缭乱,下面我把这些模式按照创建型模式,结构型模式,行为型模式分类,这样会舒服一些
一.创建型模式
意义:
- 创建型模式隐藏了这些类的实例是如何被创建和放在一起,整个系统关于这些对象所知道的是由抽象类所定义 的接口,这样,创建型模式在创建了什么,谁创建它,它是怎么被创建的,以及何时创建这些方面提供了很大的灵活
- 创建型模式抽象了实例化的过程,它们帮助一个系统独立于如何创建,组合和表示它的那些对象.
- 创建型模式都会将关于该系统使用哪些具体的类的信息封装起来.
- 允许客户用结构和功能差别很大的'产品'对象配置一个系统,配置可以使静态的,即在编译时指定,也可以是动态的,就是运行时再指定
包含的模式:
抽象工厂:
概述:提供一个创建一系列或相关依赖对象的接口,而无需指定它们具体的类
结构图:
角色及职责:
- AbstractFactory:抽象工厂接口,它里面应该包含所有的产品创建的抽象方法
- AbstractProduct:抽象产品,它们都可能有两种不同的实现
- Product:对两个抽象产品的具体分类的实现
- ConcreteFactory:具体的工厂,创建具有特定实现的产品对象
建造者:
概述:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
结构图:
角色及职责:
- Builder:是为创建一个Product对象的各个部件指定的抽象接口
- Director:是构建一个使用Builder接口的对象
- ConcreteBuilder:具体建造者,实现Builder接口,构造和装配各个部件
工厂方法:
概述:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类
结构图:
角色及职责:
- Product:定义工厂方法所创建的对象的接口
- Creator:声明工厂方法,该方法返回一个Product类型的对象
- ConcreteProduct:具体的产品,实现了Product接口
- ConcreteCreator:重定义工厂方法以返回一个ConcreteProduct实例
原型:
概述:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
结构图:
角色及职责:
- Client:让一个原型克隆自身,从而创建一个新的对象
- Prototype:原型类,声明一个克隆自身的接口
- ConcretePrototype:具体原型类,是想一个克隆自身的操作
单例:
概述:保证一个类仅有一个实例,并提供一个访问它的全局访问点
结构图:
角色及职责:
- Singleton:定义一个GetInstance操作,允许客户访问它的唯一实例.GetInstance是一个静态方法,主要负责创建自己的唯一实例
二.结构型模式
意义:
结构型设计模式是从程序的结构上解决模块之间的耦合问题
包含的模式:
适配器
概述:将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能工作在一起的那些类可以一起工作了
结构图:
角色及职责:
- 目标(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
- 适配器(Adapter):适配器模式的核心类。有两种方式实现Adapter,对象适配器(Object Adapter)和类适配器(Class Adapter)。
桥接
概述:将抽象部分与它的实现部分分离,使它们都可以独立地变化
结构图:
角色及职责:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。
组合
概述:将对象组合成树形结构以表示部分与整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性
结构图:
角色及职责:
- Component:组合中的对象声明接口,在适当情况下是想所有类共有接口的缺省行为,声明一个接口用于访问和管理 Component的子部件
- Leaf:在组合中表示叶节点对象,叶节点没有子节点
- Composite:定义有支点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加和删除
装饰
概述:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更加灵活
结构图:
角色及职责:
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
- 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任。
外观
概述:为子系统中的一组接口提供一个一直的界面,外观模式定义一个高层接口,这个接口使得这一子系统更加容易使用
结构图:
角色及职责:
- 客户(Client)
- Façade:外观类,知道哪些子系统类负责处理请求,将客户的请求代理给适当的子系统对象
- SubSystem:子系统类集合,是想子系统的功能,处理Facade对象指派的任务,注意子类中没有Facade的任何信息,即没有对Facade对象的引用
享元
概述:为运用共享技术有效地支持大量细粒度的对象
结构图:
角色及职责:
- FlyweightFactory:享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,Flyweight对象提供一个已创建的实例或者创建一个(如果不存在的话)
- Flyweight:所有具体享元类的超类或接口,通过这个接口,Flyweight可以接收并作用于外部状态
- ConcreteFlyweight:继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间
- UnsharedConcreteFlyweight:指那些不需要共享的Flyweight子类,因为Flyweight接口共享成为可能,但它并不强制共享
代理
概述:为其他对象提供一种代理以控制对这个对象的访问
结构图:
角色及职责:
- Subject:声明了真实主题和代理主题的共同接口。
- Proxy:内部包含对真实主题的引用,并且提供和真实主题角色相同的接口。
- RealSubject:定义真实的对象。
三.行为型模式
意义:
行为型模式设计到算法和对象间的职责分配,不仅描述对象或类的模式,还描述它们之间的通信方式,刻划了运行时难以跟踪的复杂的控制流,它们将你的注意力从控制流转移到对象间的关系上来。
包含的模式:
观察者
概述:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
结构图:
角色及职责:
- Subject:抽象目标角色,提供注册和删除观察者对象的接口,知道它的观察者。可以有任意多个观察者观察同一个目标。
- Observer:观察者角色,为那些在目标发生改变时需要更新的对象定义一个更新接口。
- ConcreteSubject:具体目标将有关状态存入ConcreteObserver对象,当它的状态发生改变时,向它的各个观察者发出通知。
- ConcreteObserver:具体观察者维护一个指向ConcreteSubject对象的引用,存储有关状态,这些状态应与目标状态保持一致,实现Observer的更新接口,以使自己状态与目标状态保持一致。
模板方法
概述:定义一个操作的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可定义该算法的某些特定步骤
结构图:
角色及职责:
- AbstractClass:抽象类定义一个模版方法,定义一个算法的骨架;定义抽象的原语操作,具体的子类将重定义它们以实现算法的各个步骤。该模版方法不仅调用原语操作,也调用定义在AbstractClass或其它对象中的操作。
- ConcreteClass:具体类,实现原语操作以完成算法中子类相关的特定步骤。
命令
概述:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;可以对请求排队或记录请求日志,以及支持可撤销的操作
结构图:
角色及职责:
- ConcreteCommand:讲一个接受者对象绑定一个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
- Client:创建一个具体命令对象(并可以设定它的接收者)。
- Receiver:知道如何实施与执行一个请求相关的操作。任何类都可能做一个接收者。
状态
概述:允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎修改了它的类
结构图:
角色及职责:
- Context:维护一个ConcreteState实例,这个实例定义当前状态。
- State:定义一个接口以封装与Context的一个特定状态相关的行为。
- ConcreteState:实现一个与Context的一个状态相关的行为。
职责链
概述:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止
结构图:
角色及职责:
- Handler:定义一个处理请示的接口
- ConcreteHandler:具体处理着类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则将将该请求转给它的后继者
解释器
概述:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
结构图:
角色及职责:
- Context:包含解释器之外的一些全局信息
- AbstractExpression:抽象表达式,声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享
- TerminalExpression:终结符表达式,实现与文法中的终结符相关联的解释操作
- NonterminalExpression:具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但他们却都认识中介者
访问者
概述:表示一个作用于某对象结构中的个元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
结构图:
角色及职责:
- Visitor(访问者):为该对象结构中每一个ConcreteElement声明一个Visit操作,该操作的名称和特征标志了发送Visit请求给该标识者的那个类,使访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
- ConcreteVisitor(具体访问者):实现每个Visitor声明的操作。每个操作实现本算法的一部分,而该算法片段乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态,这一状态常常在遍历该结构的过程中累积结果。
- Element(元素):定义一个Accept操作,它以一个访问者为参数。
- ConcreteElement(具体元素):实现Accept操作,该操作以一个访问者为参数。
- ObjectStructure(对象结构):可以是一个复合,提供一个高层接口以允许访问者访问它的元素,能枚举它的元素。
策略
概述:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化
结构图:
角色及职责:
- Strategy(策略):定义所有支持算法的公共接口。Context使用这个接口来调用某个Concretestrategy定义的算法。
- ConcreteStrategy(具体策略):以Strategy为接口实现某具体算法。
- Context(上下文):维护一个Strategy对象的引用,用一个ConcreteStrategy来配置,可定义一个接口来让Strategy访问它的书籍。
备忘录
概述:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态
结构图:
角色及职责:
- Memento:存储备忘发起角色的内部状态,备忘发起角色根据需要决定备忘录角色存储自己哪些内部状态。为了防止备忘发起角色以往的对象访问备忘录,管理者只能看到备忘录的窄接口——它只能把备忘录传递给其它对象,原备忘发起角色可以看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
- Originator:创建一个备忘录,用于记录当前时刻它的内部状态,在需要时使用备忘录恢复内部状态。
- Caretaker:负责管理备忘录,不能对备忘录的内容进行操作或检查。
迭代器
概述:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示
结构图:
角色及职责:
- Aggregate:聚集抽象类
- Iterator:迭代抽象类,用于定义得到开始对象,得到下一个对象,判断是否到结尾,当前对象等抽象方法,统一接口
- ConcreteAggregate:具体聚集类,继承Aggregate
- ConcreteIterator:具体迭代器类,继承Iterator,实现开始,下一个,是否结尾,当前对象等方法
设计模式的目的是为了让软件更加灵活,重用度更高。但是,某种意义上,设计模式增加了软件维护的难度,特别是它增加了对象之间关联的复杂度。所以不要什么地方都想用一个设计模式,不过设计模式确实是个好东西,用好了会让你的软件具有更高层次的提升.