读书笔记--大话设计模式--其二

装饰模式
定义
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活
需要把所需的功能按正确的顺序串联起来进行控制

 Component 是定义一个接口对象,可以给这些对象动态地添加职责。ConcreteComponent 是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator, 装饰抽象类,继承了Component 从外类来扩展Component 类的功能,但对于Component 来说,是无需知道Decorator存在的。至于ConcreteDecorator 就是具体的装饰对象,起到给Component 添加职责的功能
装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就
和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中
总结
装饰模式是为已有功能动态地添加更多功能的一种方式
当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入新的字段、新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰模式切提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为是,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了
把类中的装饰功能从类中搬移去除,这样可以简化原有的类
有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑
代理模式
定义
为其他对象提供一种代理以控制对这个对象的访问

应用
远程代理
为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实
虚拟代理
根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象
安全代理
用来控制真实对象访问时的权限、
智能指引
指当调用真实的对象时,代理处理另外一些事
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类

工厂方法模式实现时,客户端要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类的,而现在是改客户端
工厂方法模式是简单工厂模式的进一步抽象和推广。使用了多态性,保持了简单工厂模式的优点(保持封装对象创建过程),而且克服了它的缺点(违背开放-封闭原则)。缺点是每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量
原型模式
定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节
一般在初始化的信息不发生变化的情况下,克隆是最好的办法。既隐藏了对象创建的细节,又对性能是大大的提高
不用重新初始化对象,而是动态地获得对象运行时的状态
浅复制与深复制
如果方法的字段是值类型,对该字段执行逐位复制;如果字段是引用类型,则复制引用而不复制引用的对象,即引用的对象数据是不会被克隆过来的
浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其它对象的引用仍然指向原来的对象
深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象
模板方法模式
继承 就应该成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复
当我们要完成某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理
定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

特点
通过把不变行为搬迁到超类,去除子类中的重复代码来体现它的优势
提供了一个很好的代码复用平台
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬迁到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠
迪米特法则
最少知识原则
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用
在类的结构设计上,每一个类都应当尽量降低成员的访问权限。即不需要让类知道的字段或行为就不要公开(private)
根本思想是 强调了类之间的松耦合
类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成设计
外观模式
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用

在设计初期阶段,应该有意识的将不同的两个层分离,层与层之间建立外观Facade.
其次在开发阶段,子系统因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖
在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比骄傲清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作
建造者模式
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
又叫生成器模式。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需知道了
解析


主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化
好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式
观察者模式
定义
又叫发布-订阅模式
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己

特点
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不变
当一个对象的改变需要同时改变其它对象,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式
一个抽象模型有两个方面,其中一个方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用
所做的工作其实就是在接触耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化
事件委托
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其它任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数
一个委托可以搭载多个方法,所有方法被依次唤起。可以使得委托对象所搭载的方法并不需要属于同一个类
委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型
抽象工厂模式
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

优缺点
好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品
第二好处是让具体的创建实例过程与客户端分离,客户端通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中
缺点是改动较大,可以用简单工厂来改进抽象工厂
状态模式
定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类
主要解决的是 当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化

好处与用处
好处是将与特定状态的行为局部化,并且将不同状态的行为分割开来
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在与某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转移
目的是消除庞大的条件分支语句。通过把各种状态转移逻辑分布到State子类之间,来减少相互间的依赖
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了
适配器模式
定义
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用与希望复用一些现存的类,但是接口又与复用环境要求不一致的情况
有两种类型:类适配器模式(用到多重继承)、对象适配模式

何时使用
使用一个已经存在的类,但如果它的接口,也就是它的方法和你要求不相同时,就应该考虑用适配器模式
两个类所做的事情相同或相似,但是具有不同的接口时要使用它
客户代码可以统一调用统一接口,可以更简单、更直接、更紧凑
在双方都不太容易修改的时候再使用适配器模式适配

posted @ 2021-11-17 19:54  巩云龙  阅读(37)  评论(0编辑  收藏  举报