设计模式总结

来源:互联网 发布:阿里云国际版账号注册 编辑:程序博客网 时间:2024/05/23 18:20
常用模式:
1.原型模式,在model中经常会用到
2.模块方法模式,在业务逻辑层用的比较多
3.外观模式,在业务逻辑层经常用到

1.简单工厂模式(SimpleFactoryPattern):
    在简单工厂类里使用switch,调用继承工厂基类的工厂A的方法
    适用示例:计算器、超市打折

2.策略模式(StrategyPattern):
    多个策略类继承策略基类,实现具体算法,在主策略类中,声明一个策略基类变量,在初始化主策略时赋值,提供一个实现策略基类的方法。
    适用示例:检索QQ群和QQ消息


简单工厂模式和策略模式的比较:
相同点:都是将类继承,在基类中声明公用的方法和变量,在子类中实现
不同点:在“简单工厂模式”的核心类,是根据传递的变量,使用swith实例化具体的工厂类,再得到结果
        在“策略模式”的核心类,是在已经声明一个策略类基,根据传递的具体策略类A,进行赋值,再得到结果



3.装饰模式(DecorativePattern):
    为已有功能动态地添加更多功能的一种方式。
    装饰基类A继承装饰元件基类B,在装饰基类A中,声明一个装饰元件基类变量,提供一个设置这个装饰元件基类变量的方法,提供一个实现装饰元件基类的方法,多个装饰类(如:C、D、E)继承装饰基类A,实现具体算法;
    装饰类F继承装饰元件基类B,实现具体算法。首先实例化装饰类F,在F中设置这个装饰元件基类变量为C,在C中设置这个装饰元件基类变量D,在D中设置这个装饰元件基类变量E...调用具体方法,可得到结果
    适用示例:QQ形象穿衣服

4.代理模式(ProxyMode):
    为其他对象提供一种代理以控制对这个对象的访问。
    发起人类继承接口,实现方法,代理类也继承同一接口,并声明一个发起人类的变量,调用发起人变量的方法实现接口。
    适用范围:
    A.远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
    B.虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
    C.安全代理,用来控制真实对象访问时的权限。
    D.智能指引,是指当调用真实的对象时,代理处理另外一些事。

5.工厂方法模式(FactoryPattern):
    定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
    实例化运算的方法,加、减、乘、除法计算类继承计算基类,重写实现方法;加、减、乘、除法工厂类继承工厂接口,实现获取具体计算类变量的方法,调用这个方法返回的变量的方法,可以得到结果。

6.原型模式(PrototypePattern):
    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
    MemberwiseClone()方法,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
    继承接口ICloneable,实现方Clone法。
    浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
    深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

7.模块方法模式(TemplateMethod):
    所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复。
    定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
    通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。提供了一个很好的代码利用平台。
    父类定义共同的抽象方法和虚方法等,子类实现父类。
    适应场景:当我们要完成在某一细节层次一致的过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时

8.外观模式(FacadePattern):
    为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    唯一没有用到封装、继承的模式,调用多个没有关联的类的方法,实现功能。
    适用场景:
    A.首先,在设计初期阶段,应该要有意识的将不同的二个层分离。
    B.其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。增加外观Facade可以提供一个简单的接口,减少它们之间的依赖。
    C.第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,可以为新系统开发一个外观Facade类,
    来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。

9.建造者模式(BuilderPattern):
    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    具体实现类A继承基类,在指挥类中声明一个基类变量,在具体实现方法中调用基类变量的多个方法实现功能。
    适用场景:
    主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
    若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

10.观察者模式(ObserverPattern):
    又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,
    会通知所有观察者对象,使它们能够自动更新自己。
    将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。
    我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
    适用场景:
    当一个对象的改变需要同时改变其他对象的时候。

11.抽象工厂模式(AbstractFactory):
    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    抽象工厂+反射可以解决数据库重用。

12.状态模式(StatePattern):
    当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
    适用场景:
    当控制一个对象状态转换的条件表达式过于复杂时的情况下使用。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
    当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
    好处:将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。

13.适配器模式:
    将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    适用范围:
    系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。
    适配器模式主要应用于希望利用一些现存的类,但是接口又与复用环境要求不一致的情况。

14.备忘录模式(MementoPattern):
    一个发起人类包含创建、恢复备忘录信息的方法,管理者储存了备忘录的变量,以备下次发起人类进行恢复。
    适用范围:
    适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,发起人可以根据保存的备忘信息还原到前一状态。
    如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。

15.组合模式(CompositePattern):
    将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
    定义一个组合元件类,组合对象A继承元件类,并实现具体添加、删除、显示子节点的方法,组合对象B是无子节点的继承无件类的类,通过调用这二个类的方法可以组合成一棵树。
    适用范围:
    需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

16.迭代器模式(IteratorPattern):
    提供一种方法顺序访问一个聚合对象中各个元素,而不暴露该对象的内部表示。
    迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样即可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

17.单例模式(SingletonPattern):
    所有类都有构造方法,不编码则系统默认生成空的构造方法,若有显示定义的构造方法,默认的构造方法就会失效。
    概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
    饿汉式单例类:这种静态初始化的方式是在自己被加载时就将自己实例化
    懒汉式单例类:要在第一次被引用时,才会将自己实例化

18.桥接模式(BridgePattern):
    概念:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
    
19.命令模式(CommandPattern):
    将一个请求封闭为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
    优点:
    A.它能较容易地设计一个命令队列;
    B.在需要的情况下,可以较容易地将命令记入日志;
    C.允许接收请求的一方决定是否要否决要求;
    D.可以容易地实现对请求的撤销和重做;
    E.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
    多个具体命令类继承抽象命令类,指定具体命令接收对象和接收对象执行的方法,服务员类可以添加、取消、通知执行命令。

20.职责链模式(ChainResponsibilityPattern):
    当客户提交一个请求时,请示是沿链传递直至有一个ConcreteHandler对象负责处理它。
    管理者基类里面定义上级管理者变量,提供设置上级管理者和处理申请都请求的方法,管理者A、B、C实现管理者类,
    在主方法中定义管理者A、B、C的实例类,设置他们的上下级关系,实例化申请者A,调用管理者A(最小上级)的处理方法,即可得到结果。

21.中介者模式(MediatorPattern):
    也叫调停者模式
    用一个中介对象来封闭一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
    中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了“多对多”交互复杂的对象群时,
    不要急于使用中介者模式,而要先反思你的系统在设计上是不是不合理。

22.享元模式(FlyweightPattern):
    运用共享技术有效地支持大量细粒度的对象。
    享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。
    如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够受大幅度地减少需要实例化的类的数据。
    如果能把这些参数移到类实例的外面,在方法调用时就将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。
    具体网站类继承抽象类,实现初始化和具体显示方法,享元工厂类包含一个Hashtable字段,如果在Hashtable不存在则添加一个实例,否则直接读取,还提供一个返回Hashtable行数的方法。
    应用场景:
    如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;
    还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

23.解释器模式(InterpreterPattern)-298:
    给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
    应用场景:
    如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。
    这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
    
24.访问者模式(VisitorPattern)-309:
    表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
    男人和女人都继承了人的对象,并实现了具体的输出方法,成功、失败、恋爱类继承了状态对象,实现了男人和女人的输出方法,对象结构定义了List类型的人对象变量,提供了添加、移除、输出的方法。



一、创建型模式:
    创建型模式,就是用来创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。
    使用创建者模式是为了提高系统的可维护性和可扩展性,提高应对需求变化的能力!

    (1).单例模式(Singleton Pattern)解决的是实体对象的个数问题,其他的都是解决new所带来的耦合关系问题。

    (2).工厂方法模式(Factory Pattern)在工厂方法中,工厂类成为了抽象类,其实际的创建工作将由其具体子类来完成。
        工厂方法的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中去,强调的是“单个对象”的变化。

    (3).抽象工厂模式(Abstract Factory)抽象工厂是所有工厂模式中最为抽象和最具有一般性的一种形态。
        抽象工厂可以向客户提供一个接口,使得客户可以在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象,强调的是“系列对象”的变化。

    (4).建造者模式(Builder Pattern)把构造对象实例的逻辑移到了类的外部,在这个类的外部定义了这个类的构造逻辑。
        他把一个复杂对象的构造过程从对象的表示中分离出来。其直接效果是将一个复杂的对象简化为一个比较简单的目标对象。他强调的是产品的构造过程。

    (5).原型模式(Prototype Pattern)和工厂模式一样,同样对客户隐藏了对象创建工作,
        但是,与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。

二、结构型模式:
    结构型模式,顾名思义讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象,从而实现新的功能(对象结构型模式)。

    (1).适配器模式(Adapter Pattern)通过类的继承或者对象的组合侧重于转换已有的接口;
    (2).桥接模式(Bridge Pattern)通过将抽象和实现相分离,让它们可以分别独立的变化,它强调的是系统沿着多个方向的变化;
    (3).装饰模式(Decorator Pattern)采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,它强调的是扩展接口;
    (4).组合模式(Composite)模糊了简单元素和复杂元素的概念,它强调的是一种类层次式的结构;
    (5).外观模式(Façade )将复杂系统的内部子系统与客户程序之间的依赖解耦,它侧重于简化接口,更多的是一种架构模式;
    (6).享元模式(Flyweight)解决的是由于大量的细粒度对象所造成的内存开销的问题,它与Façade模式恰好相反,关注的重点是细小的对象;
    (7).代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问,它注重于增加间接层来简化复杂的问题。

三、行为型模式:
    模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、
    解释器模式、状态模式、策略模式、职责链模式、访问者模式



1.单一职责原则:一个类,应该只有一个引起它变化的原因[ASD]。
    如果一个类的职责太多,就等于这些职责都耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。
    当发生变化时,设计会遭受到意想不到的破坏。
    软件设计真正要做的许多内容,就是发现职责并将这些职责相互分离[ASD]。

2.开放-封闭原则:软件实体(类、模块、函数等)应该可以扩展,但不能修改[ASD]。
    对于扩展是开放的,对于更改是封闭的。
    面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
    无论模块是多么的封闭,都会存在一些无法对之封闭的变化。既然不可能完成封闭,设计人员必须对他设计的模块应该对哪种变化封闭做出选择。
    他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离这些变化[ASD]。
    在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的变化。
    开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,
    也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,
    然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。

3.依赖倒转原则:抽象不应该依赖细节,细节应该依赖于抽象。针对接口编程,不要对实现编程。
    A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
    B.抽象不应该依赖细节。细节应该依赖抽象。

4.里氏代换原则:一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,
    而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化。
    子类型必段能够替换掉它们的父类型。
    只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
    由于子类型的可替换性才使得使用父类类型的模块在无需修改的情况下就可以扩展。

5.迪米特法则(LOD):如果二个类不必彼此直接通信,那么这二个类不应当发生直接的相互作用。
    如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
    在类的结果设计上,每一个类都应当尽量降低成员的访问权限。
    迪米特法则其根本思想,是强调了类之间的松耦合。
    类之间的耦合弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。

6.合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用类继承。
    聚合表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;
    合成则是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
    好处:优先使用对象的合成/聚合将有助于你保持每个类被封闭,并被集中在单个任务上。
    这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。