设计模式复习总结-要点+思维导图

概要图

  • 创建型:涉及到将对象实例化,和类模式都提供一个方法,将客户从需要实例化的对象中解耦出来

  • 行为型:只要是行为型模式,都涉及到类和对象如何交互及分配职责

  • 结构型:结构型模式可以让你把类或对象组合到更大的结构中

详细总结

序号

模式划分

好处

理解总结

原则

1

策略模式:定义了一组算法(行为的具体实现),让算法间可以直接替换,不影响调用者的逻辑。

  • 如果不做区分,都放在超类中,会导致一些特有的属性,不适配所有的子类

  • 如果不给每个属性接口设计实现类,直接让子类实现接口,会导致即使接口方法的具体实现是通用的,每个接口仍要重复实现接口的方法。

  • 封装可以互换的行为,并使用委托在行为之间切换,定义算法簇,风别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

面向对象设计中,将对象的行为和属性按照变化(特有属性)和不变(固有属性)划分,不变的部分放到超类中,变化的部分,每个属性单独设计一个接口和若干实现类,并将接口组装到模型的超类中。

多用组合,少用继承。

2

观察者模式:观察者模式提供了一种对象设计,让主题和观察者之间松耦合。

  • 生产者(主题)和消费者(订阅者)解耦,双方都可以任意扩展

  • 让对象能够在状态改变时被通知,在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

向松耦合设计的方向努力,数据生产和消费的场景中,出现一对多时,考虑使用观察者的方式,一份数据可以服务多个消费场景。

主题数据发生变化时,可以主动向观察者推数据(推荐的方式),也可以仅仅通知观察者,而后观察者自己来查询变化后的数据

Java实现的Observable是类不是接口,这导致一个类继承了Observable就不能再继承别的类,这是Java observable的弊端,设计应该针对接口,而不是针对实现编程。

SwingUI组建的actionListenner也是观察者模式的一种实现

封装变化,松耦合设计

3

装饰器模式:动态的将功能附加到对象,同时这种附加有别于继承的方式附加新的属性/功能,这种附加可以被重复使用。

  • 可以让扩展更灵活,对原有逻辑侵入更小,虽然代价是类会变多一些。

  • 包装一个对象,以提供新的行为,动态的将责任附加到对象。若要扩展功能,装饰者了比继承更有弹性的替代方案

对扩展开放,对修改关闭。装饰器通过继承目标类的父类,让装饰器自身具有和目标类一样的外在表现,同时在装饰类内部,接收目标类,相当于对目标类做了一层代理。这样调用方使用装饰类和使用目标类的方式是一样的。

当出现原有的对象功能需要扩充时,应该坚持对修改关闭的原则,即使修改可以最快的解决问题,但也会因此淹没掉设计上的问题。坚持对修改关闭的原则,

4

工厂模式:定义一个工厂接口,由工厂子类决定创建的类是哪个,这样工厂接口自己是灵活的,工厂的子类也是灵活的。

  • 提高横向扩展性,类的种类增加或替换时,不需要修改调用方的代码,只需要独立扩展工厂即可

  • 提高纵向灵活性,创建逻辑和使用逻辑分离,使用方不再关心创建的具体流程,创建流程发生改变时,也不需要更改使用方的代码。

  • 工厂方法让类把实例化推迟到子类。

简单工厂:可以说算不上是工厂,只是相当于把一个创建方法放到了单独的类里面,简单工厂的问题在于,当增加新的类时,工厂类需要变更,严格的看不符合开闭原则,但这样依旧可以让代码的逻辑更清晰,创建和使用的逻辑分离

工厂方法:每个实现类都有各自的工厂,这样当类做扩充时,工厂不再需要修改,只需要为新的类创建新的工厂即可,相当于一个类又一个工厂。

抽象工厂:抽象工厂的细节是工厂模式,相当于是在工厂方法做上的设计。当一个类需要多个部分共同创建时,而每个部分又可以独立的水平扩展,此时对于部分来说,使用的是工厂方法,对于整个对象来说,是工厂里包含了多个组件的工厂。

依赖倒置原则(DIP),全称Dependence Inversion Principle,这是什么意思呢?先看下原始定义:High level modules should not depend upon low level modules.Both should depend uponabstractions.Abstractions should not depend upon details.Details should depend upon abstractions.简单来说,即是:具体类之间的关系应该依靠接口实现,但接口的设计不能依据具体的某个类。换言之也就是:面向接口编程!

5

单例模式:确保一个类只有一个实例,并且可以全局访问(静态方法)

  • 全局(一个classLoader内)共用一个实例,节约创建的资源

  • 提供全局访问点

静态变量和单例都可以实现公用,静态变量jvm启动时,就被创建了,如果静态变量依赖多方资源,就会变得麻烦。

单纯使用synchronize保证多线程下的不重复创建,但存在同步的性能问题

创建时再加同步,双层校验,使用volatile禁止指令重排(防止两次检查结果交叉)

6

命令模式:当发出命令的对象不关心执行命令的具体逻辑时,使用一个命令对象(command)实现发起命令方对执行命令方的调用。

  • 命令发起者和命令执行者之间解耦,命令发起者不关心命令的具体执行过程,命令执行者可以水平扩展

  • 将请求封装成对象,这可以让你使用不同的请求,队列,或者日志请求来参数化其他对象。命令模式也可以支持撤销操作

命令模式和策略模式都是通过接口注入不同的实现类,达到不同的操作的目的。

一个显著的区别是,策略模式的多种实现都在做同一件事,比如过滤接口有多种过滤规则,这些过滤的具体实现都在做同一件事---过滤;

命令模式的操作接口的具体实现在做不同的事,如一个指令可能对应开灯,播放音乐等不同的事情。

原因就在于,策略模式根据自身的规则操作传递的入参;而命令模式,甚至不关心入参是什么,重在操作自己关心的对象,如关灯操作关心的是灯,放音乐操作关心的是音乐播放器。

单一职责原则,英文全称Single Responsbility Property。怎样的类设计才称的上符合单一职责原则呢?一句话:应该有且仅有一个原因引起类的变更(There should never be more than one reason for a class to change)。这句话看起来文绉绉,但是等下结合例子就会发现,这句话可以贯穿单一职责原则的始终。

7

适配器模式:在不修改原有接口的情况下,将一个类的接口转换为期望的目标接口

  • 无需修改原有代码,实现接口的变更

  • 扩展性加强

  • 封装对象,并提供不同的接口,将一个类的接口,转换成客户期望另一个接口,适配器让原本不兼容的可以合作无间。

适配有两种方式:对象适配和类适配

类适配:适配器同时继承源类和目标类,这样适配器同时具有源类和目标类的能力,但是java不支持多继承。T-->A;S-->A;

对象适配:适配器继承自源类,具备源类能力,目标类继承自适配器,从而使得目标类具备源类能力

S-->A-->T;

迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP),虽然名字不同,但描述的是同一个规则。第二个名字表述的更加直白:一个类具体是怎么执行业务的我不需要知道,你只要告诉我调用那个方法就可以了。怎样才算是告诉我有哪些方法?没错,public。类的所有public 方法和变量都认为是对我公开的。也就是说:一个类对象,应该对其他的类对象的方法、变量知道的越少越好(对外开放的public类型的方法和变量应该越少越好)。

8

模版方法:抽取逻辑流程的骨架,放到抽象类里,流程的细节在子类中实现,这样,不同的子类拥有一致的业务(逻辑)流程,但拥有各自的实现

  • 提高了流程的复用性

  • 提高了业务能力的扩展性(扩展子类)

  • 对于流程固定,水平扩展的业务场景尤为有效

  • 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

模版方法是工作中最为常见的设计模式之一。模板方法把固化的流程沉淀在上层抽象类中,而每个具体环节的实现,有继承该抽象类的子类各自实现,从而实现主流程的复用,以及业务扩展的灵活性,新创建一个子类,就对应一个新的处理策略。

好莱坞原则:在模板方法模式中,子类不显式调用父类的方法,而是通过覆盖父类的方法来实现某些具体的业务逻辑,父类控制对子类的调用,这种机制被称为好莱坞原则(Hollywood Principle),好莱坞原则的定义为:“不要给我们打电话,我们会给你打电话(Don‘t call us, we’ll call you)”。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的体现了“好莱坞”原则。由父类完全控制着子类的逻辑,子类不需要调用父类,而通过父类来调用子类,子类可以实现父类的可变部份,却继承父类的逻辑,不能改变业务逻辑。 模板方法模式意图是由抽象父类控制顶级逻辑

9

状态模式

  • 状态设计成类,不同的状态有不同的处理方法

  • 与状态相关的能力更加内聚,对象主体不因状态的改变而改变

  • 封装了基于状态的行为,并使用委托在行为间切换。允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

状态模式让一个对象在不同状态时有不同的行为

状态模式用类来表示状态,与状态相关的行为也委托到状态的类里面

状态模式与策略模式使用方式相似(定义状态接口,并在主体类中引入状态接口,运行时创建状态实体类)

10

代理模式

  • 解决直接访问对象时带来的问题,包括安全控制,跨进程等

为另一个对象提供替身或占位符以访问这个对象

和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。

和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

猜你喜欢

转载自blog.csdn.net/u013821237/article/details/107625203