zoukankan      html  css  js  c++  java
  • 设计模式 复习记录

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

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

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

    设计原则:封装变化

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

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

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

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

    更好的灵活性;

    策略模式; strategy ,policy

    定义一个算法家族,封装每个,让每个是可更换的;让算法的变化独立于他的使用者;
    应用:
    1.许多相关类只有他们的行为不同;
    2. 需要一个算法的不同变体;
    3. 不让算法数据暴露给使用者;
    4. 类定义了很多行为,通过条件进行选择,可以将行为移动到策略类中;

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

    观察者模式: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()方法,进行日志记录,系统崩溃时重新执行;
    2. Java 的GUI 委派事件模型, listener的匿名类实现不同业务;
    3. 命令模式 是回调函数的对象替代;
    4. 命令对象的生存期可以独立于原始请求,

    单例模式: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一样使用;

    【参考资料】
    Freeman E, Freeman E, Sierra K, et al. Head First 设计模式[J]. 中文版中文版, 2007: 20071-36.

  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/billxxx/p/12128928.html
Copyright © 2011-2022 走看看