设计模式学习笔记

分类: 互联网 > 其他

一、设计模式简介

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

二、设计模式的类型

总共有 23 种设计模式。这些模式可以分为三大类:

    1. 创建型模式(Creational Patterns)

        这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

        1)工厂模式(Factory Pattern)

            意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

            主要解决:主要解决接口选择的问题。

            何时使用:我们明确地计划不同条件下创建不同实例时。

            如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

            关键代码:创建过程在其子类执行。

            使用场景:1. 日志记录器 2. 数据库访问 3. 数据库访问扩展

            实现步骤:

                1. 创建一个 Shape 接口和实现 Shape 接口的实体类

                2. 定义工厂类 ShapeFactory

                3. FactoryPatternDemo 类使用 ShapeFactory 来获取 Shape 对象

        2)抽象工厂模式(Abstract Factory Pattern)

            意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

            主要解决:主要解决接口选择的问题。

            何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

            如何解决:在一个产品族里面,定义多个产品。

            关键代码:在一个工厂里聚合多个同类产品。

            使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

            实现步骤:

                1. 创建 Shape 和 Color 接口和实现这些接口的实体类

                2. 创建抽象工厂类 AbstractFactory

                3. 定义工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory

                4. 创建一个工厂创造器/生成器类 FactoryProducer

                5. AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory 对象

        3)单例模式(Singleton Pattern)

            意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

            主要解决:一个全局使用的类频繁地创建与销毁。

            何时使用:当您想控制实例数目,节省系统资源的时候。

            如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

            关键代码:构造函数是私有的。

            应用实例:1. WEB 中的计数器 2. I/O链接等

            实现步骤:

                1. 创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例

                2. SingleObject 类提供了一个静态方法,供外界获取它的静态实例

        4)建造者模式(Builder Pattern)

            意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

            主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

            何时使用:一些基本部件不会变,而其组合经常变化的时候。

            如何解决:将变与不变分离开。

            关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

            使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

            实现步骤:

                1. 将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中

                2. 创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder

                3. BuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal

        5)原型模式(Prototype Pattern)

            意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

            主要解决:在运行期建立和删除原型。

            何时使用: 1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

            如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。

关键代码: 1、实现克隆操作。 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些"易变类"拥有稳定的接口。

            使用场景: 1、资源优化场景。 2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 3、性能和安全要求的场景。 4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5、一个对象多个修改者的场景。 6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

    2. 结构型模式(Structural Patterns)

        这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

        1)适配器模式(Adapter Pattern)

            意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

            主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

            何时使用: 1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。 3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

            如何解决:继承或依赖(推荐)。

            关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。

            使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

            实现步骤:

                1. 创建一个抽象类 Shape 和扩展了 Shape 类的实体类

                2. 定义类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆

                3. PrototypePatternDemo 类使用 ShapeCache 类来获取 Shape 对象

        2)桥接模式(Bridge Pattern)

            意图:将抽象部分与实现部分分离,使它们都可以独立的变化。

            主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

            何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。

            如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

            使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

            关键代码:抽象类依赖实现类。

        3)过滤器模式(Filter、Criteria Pattern)

        4)组合模式(Composite Pattern)

        5)装饰器模式(Decorator Pattern)

        6)外观模式(Facade Pattern)

        7)享元模式(Flyweight Pattern)

        8)代理模式(Proxy Pattern)

    3. 行为型模式(Behavioral Patterns)。

        这些设计模式特别关注对象之间的通信。

        1)责任链模式(Chain of Responsibility Pattern)

        2)命令模式(Command Pattern)

        3)解释器模式(Interpreter Pattern)

        4)迭代器模式(Iterator Pattern)

        5)中介者模式(Mediator Pattern)

        6)备忘录模式(Memento Pattern)

        7)观察者模式(Observer Pattern)

        8)状态模式(State Pattern)

        9)空对象模式(Null Object Pattern)

        10)策略模式(Strategy Pattern)

        11)模板模式(Template Pattern)

        12)访问者模式(Visitor Pattern)

来源:原创 发布时间:2022-07-18 23:49:15