复习资料设计模式
Posted zhangjiuding
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复习资料设计模式相关的知识,希望对你有一定的参考价值。
面向对象设计原则
- 对于面向对象的软件系统来说,在支持可维护性的同时,需要提高系统的可复用性。
- 软件的复用可以提高软件的开发效率,提高软件质量,节约开发成本,改善系统的可维护性。
- 单一职责原则要求在软件系统中,一个类只负责一个功能领域中的相应职责。
- 开闭原则要求一个软件实体应当对扩展开放,对修改关闭,即在不修改源代码的基础上扩展一个系统行为。
- 里氏代换原则:在软件中如果能够使用基类对象,那么一定能使用其子类对象。
- 依赖倒转原则要求抽象不应该依赖于细节,细节应该依赖于抽象;要针对接口编程,不要针对实现编程。
- 接口隔离原则要求客户端不应该依赖那些它不需要的接口,即将一些大的接口细化成一些小的接口工客户端使用。
- 合成复用原则要求复用时尽量使用组合对象,而不使用继承。
- 迪米特法则要求一个软件实体应当尽可能少的与其他实体发生相互作用。
简单工厂模式(类创建型模式)
- 创建型模式对类的实例化过程进行了抽象。
- 简单工厂模式专门定义一个工厂类来负责创建具体产品类的实例,被创建的实例通常具有共同的抽象产品父类。
- 简单工厂模式的优点:实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责。
- 简单工厂模式的缺点:工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。
- 简单工厂模式包含三个角色: a. 工厂角色负责实现创建所有实例的内部逻辑。 b. 抽象产品角色是创建的所有对象的父类,负责描述所有实例所有的公共接口。 c. 具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
- 在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
- 有些情况下,工厂类可以由抽象产品角色扮演,一个抽象产品类同时也是子类的工厂,也就是说把静态工厂方法写到抽象产品类中。
- 有些情况下,工厂、抽象产品和具体产品三个角色可以合并,它们即是工厂,有通过静态工厂方法创建一个自己的实例,通过合并,可以对简单工厂模式进行简化。
创造者模式(对象创建型模式)
- 创造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的实例。
- 建造者模式是一步步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
- 建造者模式的优点: a. 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。 b. 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,符合开闭原则。 c. 可以更加精细的控制产品的创建过程。
- 建造者模式的缺点: a. 由于建造者模式所创建的产品一般都具有较多的共同点,其组成部分相似,因此其使用范围受到一定的限制。 b. 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得庞大。
- 建造者模式包含如下四个角色:
a. 抽象建造者为创建一个产品对象的各个部件指定抽象接口。
b. 具体建造者实现了抽象建造者接口,实现各个部件的构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
c. 产品角色是被构建的复杂对象,包含多个组成部件。
d. 指挥者负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。
- 在建造者模式的结构中引入了一个指挥者类,该类的主要作用有两个: a. 隔离了客户与生产过程。 b. 负责控制产品的生产过程。
- 指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过指挥者类调动建造者的相关方法,返回一个完整的产品对象。
- 建造者模式的简化: a. 省略抽象建造者角色:如果系统只需要一个具体建造者可以省略抽象建造者。 b. 省略指挥者角色:如果已经省略了抽象建造者,那么还可以省略指挥者,让建造者扮演指挥者和建造者双重角色。
- 建造者模式与抽象工厂模式比较: a. 建造者模式返回一个完整的产品;抽象工厂模式返回一个产品族。 b. 抽象工厂模式可以看做汽车配件工厂,生产一系列配件;建造者模式可以看做汽车组装工厂,对配件进行组装,生产出一个完整的汽车。
原型模式(对象创建型模式)
- 用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。原型模式允许一个对象再创建另一个可定制的对象,无须知道任何创建细节。
- 原型模式的基本工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝原型自己来实现创建过程。
- 原型模式的优点:可以快速创建很多相同或相似的对象,简化对象的创建过程,还可以保存对象的一些中间状态。
- 原型模式的缺点:需要为每一个类配备一个克隆方法,因此对已有类进行改造比较麻烦,需要修改其源代码,并且在实现深克隆时需要编写较为复杂的代码。
- 原型模式包含三个角色: a. 抽象原型类:定义具有克隆自己的方法的接口。 b. 具体原型类:实现具体的克隆方法,在克隆方法中返回自己的一个克隆对象,让一个原型克隆自身从而创建一个新的对象。 c. 在客户类:只需要直接实例化或通过工厂方法等方式创建一个对象,再通过调用该对象的克隆方法复制得到多个相同的对象。
- 在浅克隆中,当对象被复制时它所包含的成员对象却没有被复制;在深克隆中,除了对象本身被复制外,对象包含的引用也被复制,也就是其中的成员对象也将复制。
- 在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆;如果需要实现深克隆,可以通过序列化等方式来实现。
单例模式(对象创建型模式)
- 单例模式的要点有三个: a. 单例类只能有一个实例。 b. 它必须自行实例化这个实例。 c. 它必须自行向整个系统提供这个实例。 d. 提供全局访问方法。
- 单例类拥有一个私有构造函数,确保用户无法通过new关键字直接实例化它。除此之外,该模式中包含一个静态私有成员变量与静态公有的工厂方法。
- 该工厂方法负责检验实例的存在性并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。
- 单例模式的优点:提供了对唯一实例的受控访问并可以节约系统资源。
- 单例模式的缺点:因为缺少抽象层而难以扩展,且单例类职责过重。
- 饿汉式单例类:这个类被加载时,静态变量instance会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。
- 懒汉式单例类:这个类在第一次被引用时将自己实例化,在懒汉式单例类被加载时不会将自己实例化。
适配器模式(类结构性模式或对象结构型模式)
- 结构型模式描述如何将类或者对象结合在一起形成更大的结构。
- 适配器模式用于将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器。
- 适配器模式的优点:将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合“开闭原则”。
- 类适配器模式的缺点:适配器类在很多编程语言中不能同时适配多个适配者类。
- 对象适配器模式的缺点:很难置换适配者类的方法。
适配器模式包含四个角色:
a. 目标抽象类定义客户要用的特定领域的接口。 b. 适配器类可以调用另一个接口,作为一个转换器,对适配者和抽象目标类进行适配,它是适配器模式的核心。 c. 适配者类是被适配的角色,它定义了一个已经存在的接口,这个接口需要适配 d. 在客户类中针对目标抽象类进行编程,调用在目标抽象类中定义的业务方法。
- 默认适配者模式:当不需要全部实现接口提供的方法时,可以设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口的所有方法的情况。
- 默认适配者模式有三个角色: a. 适配者接口:适配者是被适配的对象。 b. 默认适配器类:默认适配器类是默认适配器中适配器角色,它是该模式的核心。默认适配类使用空方法的形式实现了在接口中声明的方法。 c. 具体业务类:是适配器类的子类,在没有引入适配器类之前,它需要实现适配者接口,因此需要实现在适配者接口中定义的所有方法,而一些无用的方法也提供空实现。为了简化操作,在有了适配器类之后,可以直切继承该适配器类,根据需要有选择地覆盖在适配器类中定义的方法。
双向适配器:在对象适配器的使用过程中,如果在适配器中同时包含对目标类和适配器类的引用,适配者可以通过他调用目标类的方法,目标类也可以通过它调用适配者类中的方法,那么该适配器就是一个双向适配器。
组合模式(对象结构型模式)
- 组合模式用于组合多个对象形成树形结构以表示“整体-部分”的结构层次。
- 组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
- 组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。
组合模式的优点:
a. 可以方便地对层次结构进行控制,客户端调用简单。 b. 由于客户端使用构件的一致性,简化了客户端代码。- 组合模式的缺点: a. 使设计变得更加抽象,且增加新构件时可能会产生一些问题。 b. 很难对容器中的构件类型进行限制。
- 组合模式包含三个角色: a. 抽象构件为叶子构件和容器构件对象声明接口。 b. 叶子构件在组合结构中表示叶子节点对象,叶子节点没有子节点。 c. 容器构件在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为。
- 组合模式根据抽象构件类的定义形式,又可以分为透明组合模式和安全组合模式。
- 更复杂的组合模式:组合模式中的叶子构件和容器构件都可以是抽象构建,此时可以增加多个具体叶子构件和多个具体容器构件。
透明组合模式和安全组合模式:
装饰模式(对象结构型模式)
- 装饰模式用于动态地给一个对象增加一些额外的职责,使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
装饰模式的优点:
a. 可以提供比继承更多的灵活性。 b. 可以通过一种动态的方式来扩展一个对象的功能,并通过使用不同的具体装饰类以及这些装饰类的排列组合,来实现不同的构件。 c. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类。- 装饰模式的缺点: a. 使用装饰模式进行系统设计时将产生很多小对象。 b. 装饰模式比继承更加易于出错,排错也很困难。
- 装饰模式包含四个角色: a. 抽象构件定义了对象的接口,可以给这些对象动态增加职责(方法)。 b. 具体构件定义了具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。 c. 抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。 d. 具体装饰类是抽象装饰类的子类,负责向构件添加新的职责。
装饰模式可分为透明装饰模式和半透明装饰模式。
观察者模式(对象行为型模式)
- 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
观察者模式的优点:
a. 可以实现表示层和数据逻辑层的分离。 b. 并在观察目标和观察者之间建立一个抽象的耦合。- 观察者模式的缺点: a. 如果一个观察目标对象有很多观察者的话,将所有的观察者都通知到会花费很多时间。 b. 如果在观察者和观察目标之间有循环依赖的话可能导致系统崩溃。
- 观察者模式包含四个角色:
a. 目标又称为主题,它是指被观察的对象。
b. 具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。
c. 观察者将对观察目标的改变做出反应。
d. 在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
状态模式(对象行为型模式)
- 状态模式描述了对象状态的变化以及对象如何在每一种状态下表现出不同的行为。
状态模式的优点:
a. 封装了转换规则,并枚举可能的状态。 b. 它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态。 c. 只需要改变对象状态即可改变对象的行为。 d. 还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。- 状态模式的缺点 a. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 b. 不满足“开闭原则”。
- 状态模式包含三个角色:
a. 环境类又称为上下文类,它是拥有状态的对象,在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象,可以定义初始状态。
b. 抽象状态类用于定义一个接口以封装与环境类的一个特定状态相关的行为。
c. 具体状态类是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。
策略模式(对象行为型模式)
- 在策略模式中定义了一系列算法,将每一个算法封装起来,并让它们可以相互替换。
- 策略模式让算法独立于使用它的客户而变化。
- 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。
- 策略模式通常把一个系列的算法封装到一系列的策略类里面,作为抽象策略类的子类。
策略模式的优点:
a. 对“开闭原则”的完美支持,在不修改原有系统的基础上可以更换算法或者增加新的算法。 b. 它很好地管理算法族,提高了代码的复用性。 c. 替换继承,避免多重条件转移语句的实现方式。- 策略模式的缺点:客户端必须知道所有的策略类,并理解其区别。
- 策略模式包含三个角色:
a. 环境类在解决某个问题时可以采用多种策略,在环境类中维护一个对抽象策略类的引用实例。
b. 抽象策略类为所支持的算法声明了抽象方法,是所有策略类的父类。
c. 具体策略类实现了在抽象策略类中定义的算法。
以上是关于复习资料设计模式的主要内容,如果未能解决你的问题,请参考以下文章