大话设计模式 读书笔记 02

大话设计模式 02

导航

原型模式

用原型实例置顶创建对象的种类,并通过拷贝这些原型创建新的对象。

原型模式其实就是从一个对象在创建另一个可定制的对象,而且不需要知道任何创建细节。

通过成员的逐一拷贝实现。

在初始化信息不变的情况下,克隆是最好的方法,即隐藏了对象创建的细节,又对性能是大大的提高。

不用重新初始化对象,而是动态地获得对象运行时的状态。

深复制与浅复制

深复制:对成员值逐位复制,引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然执行原来的对象。

模版方法模式

使用背景

当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑模版方法模式来处理。

定义一个操作中的算法的骨架,将一些步骤延迟到子类中,模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模版方法模式通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。(是一个很好的代码复用平台)

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

迪米特法则(LoD)

最少知识原则

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

在类的结构设计上,每一个类都应当尽量降低成员的访问权限。强调了类之间的松耦合。

类之间的耦合越弱,越有利于复用,一个处在若耦合的类被修改,不会对有关系的类造成波![](file:///Users/guyu/Library/Application Support/marktext/images/2020-10-18-16-36-16-image.png)及。

外观模式

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

使用场景

  • 设计初期:有意识的将不同层分离,层与层之间建立外观Facade。

  • 开发阶段:子系统往往因为不断的重构演化变得负责,增加外观Facade提供一个简单的接口,减少它们之间的依赖

  • 维护阶段:系统已经非常难以维护和拓展了,为新的系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂工作。

建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

通过建造者模式,用户只需要指定需要建造的的类型就可以得到它们,而具体建造的过程和细节就不需要找到了。

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

ConcreteBuilder:实现Builder接口,构造和装配各个部件。

Product:具体的产品

Director:指挥者构建一个使用Builder接口的对象

使用背景

创建一些复杂的对象,这些对象内部构建间的构建顺序通常是未定的,但对象内部的构建通常面临复杂的变化

好处

构建代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的构造者就可以了。

观察者模式

发布-订阅模式 (Publish/Subscribe)

定义了一种一对多的依赖关系,让多个观察者对象同时舰艇某一个主题对象。这个主题对象在状态发生变化时,虎同志所有观察者对象,使它们能自动更新自己。

![](file:///Users/guyu/Library/Application Support/marktext/images/2020-10-18-17-10-54-image.png)

使用动机

将一个系统分割成一些列相互写作的类又一个很不好的副作用,就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类锦觅耦合,这样会给维护、扩展和重用都带来不便。

解除耦合在于提取抽象

使用时机

当一个对象的改变需要同时改变其他对象

而且它不知道具体有多少对象待改变时,应该考虑使用观察者模式。

当一个抽象模型有两个方面,一个方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们个子独立地改变和复用。

观察者模式所做的工作其实就是在接触耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化

不足

尽管使用了依赖导致原则但是抽象通知依旧依赖与抽象通知者。

可以通过事件委托来解决这层依赖

委托

委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数。

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

抽象工厂模式

回顾工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。

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

优点

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

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

缺点

增加Project时需要改变和增加的类代码过多(增加AbstractProductC和Factory对应的实例,给工厂接口和实例增加方法)

通过简单工厂优化

抛弃了工厂的接口和实例,使用DataAccess取而代之,预先设置DB值不需要输入参数,达到解耦目的。

使用反射+配置文件对抽象工厂进行进一步优化

(开放封闭原则:对于扩展是开放的对于修改是封闭的)

对于简单工厂的地方可以考虑使用反射技术去除switch或if,解除分支判断带来的耦合

状态模式

面向对象设计就是希望做到代码的责任分解

当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

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

好处

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

消除庞大的分支语句,通过将各种状态转移类;偶记分不到State的子类之间,来减少相互间的依赖。

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,可以考虑使用状态模式。

适配器模式

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

系统的数据和行为都正确,但是接口不符时,我们应该考虑用适配器,目的时使控制范围之外的一个原有对象与接口匹配。适配器模式主要应用于希望服用一些现存的类,但是接口又与服用环境要求不一致的情况。

适配器模式类型:类适配器模式,对象适配器模式

类适配器模式:多重继承

对象适配器模式:

使用时机

使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。

客户代码可以统一调用同一个接口,实现更简单,更直接,更紧凑。

备忘录模式

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

备份的细节封装在Memento中,需要更改保存细节不影响客户端使用。

备忘录模式比较适用于功能比较复杂,但需要维护或记录属性历史的类,需要保存的属性知识众多属性中的一小部分是,Originator可以根据保存的Memento信息回溯到前一状态。

使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。

当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

posted @ 2020-10-18 19:47  古宇29  阅读(68)  评论(0)    收藏  举报