设计模式:总览篇幅

设计模式

UML图示表示

1.依赖关系:A——>B   B作为A的方法调用参数

2.关联关系:A——>B   B作为A的成员变量(暗示两个类在概念上处于相同级别)

3.聚合关系:A<>——>B B作为A的成员变量(整体/局部关系,暗示整体比局部高一个级别)

4.合成关系:A——>B   B作为A的成员变量(整体要么负责局部存活状态,要么负责销毁局部。局部不可与其他整体共享)

5.继承关系:A——1 >B A作为B的子类

6.实现关系:A——1>B   A实现接口B

设计模式六大原则:

单一责任:抽象、逻辑抽取[方便复用,代码的自定义]

依赖倒置:依赖于抽象接口协议,而不依赖于具体类

里氏替换:子类完全替换父类的功能

开放封闭:修改关闭,拓展开放

接口隔离:面向最小接口面层,避免接口臃肿

迪米特法则:最少知识原则[]

总结:设计原则是让合适的代码放到合适的位置方便服用,减少代码冗余。

解耦合用:接口+继承[依赖倒置][开闭原则]

具体类:接口[单一责任][接口隔离]

如何写子类:[里氏替换]

类间交互:[最小知识]

 

设计模式

1适配器模式Adapter

定义:将一个类的接口转换为客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类一起工作。

结构图

类适配器:多继承实现

对象适配器:很像代理模式

何时使用

1事后补救:接口调用和被调用方接口都不能修改情况下,为了实现复用该功能一致但接口不同的代码,来使用适配器

2封装第三方接口:我们不希望我们系统的接口随着外部的第三方接口改变而改变、

区别代理模式:

相同点:都是讲被调用方作为属性使用

不同点:

1适配器中的代理:是已经实现的实体类,不是接口。[适配器模式需要适配器继承调用方,然后在调用方接口函数中调用该代理方法]

2代理模式中的代理:在委托中是一个接口,我们不知道代理会具体做什么,但知道调用时机。[使用时主要继承接口成为代理,然后在代理方法中具体做]

 

2简单工厂模式

定义  :用一个类封装子类实例的初始化操作

结构图

何时使用

1重复调用初始化操作,减轻用户初始化负担

2重复调用一些事先可以确定的初始化操作,那么放到工厂类中

 

3策略模式

定义 :定义了算法家族,分别用子类封装,彼此可以相互替换,此模式让算法的变化,不会影响到算法的客户。

结构图

何时使用:

1封装不同算法\不同业务规则

2减少算法类和算法调用类之间的耦合

优点:方便进行单元测试,每个算法都有自己的接口类,可以通过自己的接口来单独进行测试

 

 

4装饰者模式

定义:动态地给一个对象添加一些额外职责。增加功能:装饰模式比生成子类更加灵活

结构图

何时使用

1使用时机:增加额外职责

2实现原理:通过SetComponent来对对对象进行包装,每个装饰对象的实现就和如何使用这个对象分离。每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

个人理解

有点像链表,所有的装饰都可以放入到链表的节点中,然后最后的装饰节点输出会递归地返回上一个节点的输出,这样就给对象增加了不同顺序的功能。

 

5代理模式

定义  :将自己想做的事情定义一个接口委托给别人代理实现,然后自己拥有这个对象。自己决定它的调用方法和调用时间,但方法具体由代理决定

结构图

何时使用:委托方知道调用时机,但不知道具体执行操作。

 

6工厂方法模式(开放封闭原则)

定义  :定义一个用于创建对象的接口,让子类决定实例化哪个类。

工厂方法使一个类的实例化延迟到子类。

结构图

区别

简单工厂模式:包含必要的逻辑判断,根据客户端的选择条件动态实例化相关类。[对于客户端来说,去除了与具体产品类名的依赖,但是违反了开闭原则]—增加产品,修改简单工厂模式内部代码

工厂方法模式:必要的逻辑判断放到了客户端代码执行,客户端需要决定实例化哪一个工厂来实现产品[选择判断的问题还是存在,满足开闭原则]—增加产品,修改客户端代码

 

7原型模式

定义 :原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象

结构图:

理解:

1原型模式:从一个对象创建出另外一个可以定制的对象,而且不需要知道任何创建细节。实现一个clone接口即可

2注意浅拷贝和深拷贝到的区别,

浅拷贝:修改一次就可以修改多个副本

深拷贝:每个副本都可以修改

 

8模板方法模式

定义  定义操作中的算法骨架,而将一些步骤延迟到子类中。

模板方法使子类可以不改变算法的结构,可重定义该算法的

结构图

特点 

1通过把不变的行为搬移到弗雷中,去除子类中的重复代码来体现它的优势

2当不变和可变行为在方法的子类实现中混合在一起的时候,不变行为的在子类重复出现。我们通过模板方法模式把这些行为搬移到一个单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

 

9外观模式

定义  为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口是这一子系统更加容易使用。

外观模式知道哪些子类负责处理请求,将客户的请求代理给适当的子系统对象

结构图

何时使用

1在设计初期,应该要有意识的将不同的两个层分离,层与层之间建立外观模式

2在开发阶段,子系统因为不断地重构演化而变得越来越复杂,增加外观模式可以提供一个简单接口,减少他们之间的依赖

3在维护一个遗留的大型系统时,可能这个系统已经非常难于维护和扩展了,此时可以为新系统开发一个外观类,来提供设计粗糙或高度复杂的遗留代码的比较清晰的接口,让新系统与外观类对象交互,Facde与遗留代码交互所有复杂的工作。

区别

适配器模式:面向接口

外观模式: 面向子系统,符合有限知识原则\迪米特原则

 

10建造者模式

定义: 分离一个复杂对象的构建与表示,同样的构建过程可以创建不同的表示

结构图

特点:分离复杂对象的构建与表示,使得同样的构造过程创建不同的表示。[如果我们使用了建造者模式,那么用户只需要建造的类型就可以得到他们,而具体建造过程和细节不用知道]

1Builder:为创建一个Product对象的各个部件指定的抽象接口

2ConcreteBuilder:具体的建造者,实现Builder接口,构造和装配各个部件。

3Product:具体的产品角色

4Director:指挥者,用来根据用户的需求创建的小人对象

何时使用

主要用来创建比较复杂的对象,这些对象内部构建顺序通常

 

11观察者模式

定义: 定义一对多的依赖关系,让多个观察者同事监听某一个主题对象。这个主题对象早状态发生变化时,通知所有的观察者对象,使他们能够自动更新自己。

结构图:

何时使用

1将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就需要维护相关对象之间的一致性。为了维持一致性而使各类紧密耦合,这样会给维护,扩展和重用都带来不便。

2当一个对象的改变需要同时改变其他对象时候,而且不知道有多少对象有待改变

3观察者模式所做的事情是在解耦合,让耦合的双方都依赖于抽象而不是依赖于具体,从而使得各自的变化都不影响另一边的变化

委托事件

1观察者模式的缺点:通职者要在自己的通知方法中遍历所有的观察者,然后调用这些对象相同的方法,实际情况中可能这些对象想要执行的方法并没有相同的函数名字

2使用委托:委托一种引用类型。一旦为委托分配了方法,那么委托将代表一个具体的函数。

3一个委托可以搭载多个方法,所有的方法将会被依次唤醒

4可以使得委托对象所搭载的方法不属于同一个类

5委托对象所搭载的方法必须具有相同的原形和形式,即相同的参数列表和返回值类型。

 

12抽象工厂模式

定义    提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类

结构图 

何时使用:当只有一个产品系列的时候,只需要使用工厂方法。多个产品系统,需要使用抽象工厂模式。

优点

1易于交换产品系列,由于具体共产类在一个应用中代表着从产品系,只需要初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,只需要改变具体的工厂类,就可以使用不同的产品配置

2具体的创建实例过程与客户端分离。[客户端通过抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中]

缺点:当增加新的功能(产品)时候,我们需要修改Factory接口以及具体的Factory实现来满足要求,不满足封闭性原则

改进

1使用简单工厂模式可以有效改善增加新产品问题。[只需要添加产品,然后在简单工厂添加case语句]

2再进一步,使用反射去除case语句,只需要修改对应的类名字符串。此时的字符串如果定义在工厂内部,那么可以使用配置文件配置。然后让该字段读取该配置文件解决;当然也可以放在参数里面,由调用方决定使用哪一个,但可能会更改多次

 

13状态模式

定义  当一个对象的内在状态发生改变,允许改变其行为,这个对象看起来像改变了其类

结构图

何时使用: 主要解决-当控制一个对象状态转换条件的条件表达式过于复杂时的情况。把状态的判断条件转移到表示不同状态的一些列类当中,可以把复杂的判断逻辑简化。

优点—相当于活字印刷术

1将与特定状态相关的行为局部化,并且将不同的状态行为分割开。

2将特定的状态相关的行为放到一个对象中,由于所有与状态相关的代码都存在于某一个ConcereateState中,所以通过定义新的子类可以很容易增加新的状态和转换。

3消除庞大的条件分之语句,状态模式通过将各种状态逻辑分不到state的子类中,来减少相互间的依赖。[好比把整个版面改成一个活字]

 

14备忘录模式

定义   在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态

结构图

何时使用:

1把要保存的细节全部封装在Memonto,客户端在保存和恢复过程中不需了解细节。

2Memonto模式适用于功能比较复杂,但需要维护或记录属性历史的类,或者需要保存到属性知识众多属性中的一小部分。

缺点:角色状态信息要完整地保存在备忘录对象中,数据太多,会很占内存。

猜你喜欢

转载自blog.csdn.net/ddhmbbklyk2018/article/details/81568633