设计模式 复习记录

好的面向对象设计具有复用性,灵活性,可维护性;
设计模式告诉你如何设计一个高OO质量的系统;
设计模式是经过验证的面向对象经验;为反复出现的特定问题提供通用的解决方案;
与代码重用不同,使用设计模式可以获得经验重用;
每个模式描述了一个反复出现的面向对象问题,以及他的通用的解决方案;

设计模式四个组成:名称,问题,解决方案,影响;

Inheritance 继承
Change 变化;导致变化的因素很多,代码改变快

设计原则:封装变化

识别应用中变化的部分,把他与不变的部分分隔开;
封装变化的部分,修改时就不会影响不变的部分

设计原则:面向接口而不是实现;

Polymorphism 多态
就是面向超类,对象使用父类而不是具体子类定义,这样对象定义时不需要知道具体类型;
这个超类 可以是class 可以是interface
优点:得到复用的好处,又没有继承带来的负担

设计原则:组合比继承更好;has-a比is-a更好;

更好的灵活性;

策略模式; strategy ,policy

定义一个算法家族,封装每个,让每个是可更换的;让算法的变化独立于他的使用者;
应用:
1.许多相关类只有他们的行为不同;

  1. 需要一个算法的不同变体;
  2. 不让算法数据暴露给使用者;
  3. 类定义了很多行为,通过条件进行选择,可以将行为移动到策略类中;

    影响:替代子类化的方法;策略模式消除了选择语句;用户必须了解各种策略的不同去选择合适的;增加对象数量;

观察者模式:observer,dependents,publish-subscribe

定义了对象间一对多的依赖,当一个对象(发布者)改变状态,所有依赖者被通知并自动更新;
一对多关系:发布者唯一拥有state,observer依赖发布者更新自己when状态变化时;
更加清晰,相比于多个对象拥有相同的数据; subject和observer之间松耦合;

Subject维护observer的数组; observer维护subject的引用,解除关系时使用;
Java内置Observable类(subject)和Observer接口;【observable类限制了子类的继承,理论上可以使用组合,但是setChanged()方法是protected,所以不行;可以自己实现】
应用:GUI,界面和数据进行交互;
实现:当subject很多observer很少,可使用hashMap进行关系映射,减少subject维护的数据量;
一个observer对应多个subject,将subject作为arg传入update(), 方便observer知道执行那个subject;
调用update():subject改变状态通知后,调用update,不用client关心,但是可能导致连续多次update(),效率低;
Client在特定时间调用notify,可在一系列op后调用,缺点是client可能忘记;
Push:subject推送全数据到observer,不管他要不要;pull:sub进行通知,由obs自己用引用去取数据;
Pull让sub忽略obs,但强调obs要知道什么数据变了;push让sub更低重用,coz对ops的假设不一定对;
显示指定感兴趣修改当obs加入sub时,当某事发生时,sub通知特定的obs,(通过维护不同数组);
变体:changeManager, 维护obs和sub的复杂映射关系,定义update策略,(eg,一个op导致多个sub变化,manager在全部sub都改变后在通知obs,防止对obs的重复通知);

影响:独立的改变sub和obs,不会影响对方;
Sub只知道obs实现了接口,不知道具体实现,耦合低;双方可以属于系统的不同层次;
因为Obs不知道各自的存在,所以对sub改变的代价很盲目,可能导致obs的级联update;没有很好维护的依赖可能导致错误的update,很难追踪;

设计原则:尽量使交互的对象之间松耦合;

更加接纳变更的灵活系统;

装饰者模式:Decorator,wrapper

Decorator和decorated拥有同一个超类;
装饰着修改了comp的行为,通过添加新的功能,在调用comp的方法的之前和/或之后;
动态地向对象附加了额外的职责,为扩展功能提供了灵活的方法 替代子类化;

应用:Java IO相关的类,stream
动机

  1. 添加职责到单独的对象,而不是整个类,比如GUI构件根据不同需求的组合;
  2. 保持comp类的轻量级;最顶层的超类只是定义接口,不要存储数据;否则太重让他不能大量使用,且子类可能拥有不需要的功能;
  3. 表面vs内部; 装饰者模式是改变行为的皮肤,策略模式改变行为的内部;
    当comp类本质上很重时,使用策略,装饰者成本很高;策略模式中comp将行为转化为单独的策略对象;

开闭原则:类应该对扩展开放,对修改关闭;

(不需要在所有地方使用,是浪费的,导致过度复杂)
组合和委托 通常可以用于在运行时添加新的行为;

工厂方法模式:factory method,

定义一个创建对象的接口,让子类确定实例化哪一个类;

依赖倒置原则:依赖抽象,不要依赖具体的类;

高层类必要依赖底层类,双方都依赖于抽象。
“倒置”是指top-to-down的依赖关系颠倒了自己,top和down都依赖于抽象。
指导方针:

  1. 任何变量不应有具体类的引用,使用工厂方法得到对象;
  2. 任何类不应派生自具体类,使用接口或抽象类;
  3. 任何方法不应覆盖基类方法;说明基类不是真正抽象; (指导方针只要争取,不用作为遵守的原则)

抽象工厂方法模式:abstract factory method,

提供一个生产一系列关联产品族的接口(抽象工厂);
常见相关的一系列产品,而不与具体类耦合;

命令模式:command,action,transaction

将“请求”封装成对象,以使用不同的请求、队列、日志来参数化其他对象,支持撤销操作。
命令对象包装动作和接收者,只暴露execute()方法;将发出请求的对象和执行请求的对象解耦,通过命令沟通;

撤销undo()方法:内容和execute()方法相反;当调用一个命令execute(),就将invoker的undoCommand置为该命令;
动机:1.解耦请求的操作和请求的执行者;
应用:
1.日志,store()和load()方法,进行日志记录,系统崩溃时重新执行;

  1. Java 的GUI 委派事件模型, listener的匿名类实现不同业务;
  2. 命令模式 是回调函数的对象替代;
  3. 命令对象的生存期可以独立于原始请求,

单例模式:singleton

公共静态get方法,私有构造方法,

  1. 提前加载:使用静态field,在定义时进行new;
  2. 懒加载: 异步安全:
        Public static synchronized Singleton getInstance(){
            If(instance == null) instance = new Singleton(); 
            Return instance;
        }
双重检查:
        Public static Singleton getInstance(){
            If(instance == null) { 
synchronized (Singleton.class){
if(instance == null) instance = new Singleton(); 
                }
            }
            Return instance;
        }

适配器模式:adapter,wrapper

将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。
Target:定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。
Adapter:它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。
Adaptee:适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。
执行逻辑:Client需要调用adaptee的功能,但是他只能以target的方法来调用;adapter实现target接口,继承adaptee或者得到一个adaptee成员,在request()方法内部调用adaptee的方法; Client调用实现了target接口的adapter就行,不用去使用adaptee;

adapter可以继承adaptee类, 也可以将adapteee作为field保存在adapter类里面;

外观模式 façade:

提供一个标准接口,包装子系统一系列操作,将client从子系统一系列组件中解耦出来;

最少知识原则:仅仅和你最紧密的类交谈;

对象的方法内只能调用:
对象本身的方法;作为参数传入的对象的方法;方法内创建的对象的方法;对象的field的方法;
过度使用会让系统的复杂性增高;

适配器模式包装一个对象 去改变他的接口;
装饰模式 包装一个对象 来添加新的行为职责;
外观模式 包装一系列对象来简化功能;

模板方法模式:template method

在方法中定义算法的框架,将定义推迟到子类。允许子类在不改变算法框架的情况下,重定义算法的某些步骤。

可以在templateMethod()方法中添加hook()方法,目的是让子类可以选择是否添加步骤;

迭代器模式:iterator

封装迭代,不让client了解到聚合对象的具体实现;

单一职责原则:一个类只应该因为一个原因而变化。

组合模式:Composite

让client能相同地处理单一对象和组合对象;
以树的形式构建对象的结构,树包含对象的组合和作为节点的单个对象;
组合模式让我们可以对复合对象和单个对象应用相同的操作。

状态模式:state

当对象的内部状态变化时,允许他改变自己的行为;

策略模式通常使用行为或算法配置上下文类。
状态模式允许上下文在上下文状态更改时更改其行为。

代理模式:proxy

代理模式为另一个对象提供代理项或占位符以控制对它的访问。

Realsubject是做真正工作的对象,proxy控制对他的访问;
Proxy保存realsubject的引用,管理对realsubject的调用,proxy进行realsubject的创建工作;
Subject接口,由realsubject和proxy共同实现,client可以把proxy当成realsubject一样使用;

猜你喜欢

转载自www.cnblogs.com/billxxx/p/12128928.html
今日推荐