设计模式要点 -- Head First 设计模式

 

1 设计模式要点 – Head First 设计模式

 

1.1 TODO 设计原则

 

1.1.1 隔离变化与稳定.

几乎每个设计模式背后的精神所在. 改变不影响稳定部分.

1.1.2 针对接口编程, 而不是针对实现编程.

隔离变化的一种方式
针对超类型编程, 即接口或抽象类.
利用了多态, 不受具体类型限制, 实际能使用不同的具体实现类.

1.1.3 多用组合, 少用继承

剥离变化, 且能够动态改变行为.

1.1.4 为了交互对象之间的松耦合设计而努力.

1.1.5 类应该对扩展开放, 对修改关闭

不修改类的代码, 就能扩展功能. 组件化. 其实也是隔离变化与稳定.

1.1.6 依赖倒置原则.

要依赖抽象, 不要依赖具体类.

类似针对接口编程. 更强调抽象的思维过程.
不能让高层组件依赖具体底层组件, 两者都应该依赖于抽象. 由抽象衔接起来

倒置体现在:

  1. 类图. 使用(向下箭头) –变成了-> 实现(向上箭头)
    store(上层组件)使用具体pizza(下层组件) –变成了-> 具体pizza(下层组件)实现pizza抽象
  2. 思维. store有pizza –变成了-> 有pizza, 抽象后 给store使用

1.2 TODO 设计模式

 

1.2.1 策略模式

问题场景: Duck基类, 多种子类. 增加fly()方法.

  1. 使用继承
    基类中增加fly(). 导致:
    • 直接导致所有子类都有fly().
    • 子类差异化fly()需要覆盖.

    新增功能fly()是差异化的功能. 继承体系不变处理新增的差异化.

  2. 使用接口
    增加flyable接口, 子类实现接口. 导致:
    • 每个子类都需要实现, 代码复用差. 而且Duck类就没有fly了, 不便使用多态.
  3. 使用策略模式
    增加flyable接口. 实现一族flyable. 设计原则 体现:隔离变化. 针对接口编程
    子类增加flyable成员. 多用组合, 少用继承
    将flyable的实现 动态赋予 子类flayble成员, 通过构造或者set.

策略模式:定义了算法族, 分别封装起来, 让它们之间可以互换. 算法独立于算法的使用者.

1.2.2 观察者模式

观察者模式:一个对象(subject)状态改变, 通知 依赖者(observer) 有状态更新. 一对多的关系.
subject中只使用observer接口. 设计原则 体现: 针对接口编程. 不依赖observer的具体实现

如果不用观察者模式, 依赖者(观察者)就要编码到 subject(被观察对象)中. 设计原则 体现: 交互对象松耦合
新增依赖者, 就需要改subject的代码. 设计原则 体现: 隔离变化与稳定. subject稳定, observer可能增减

1.2.3 装饰者模式

问题场景: 基础饮料 + 配料 = 饮品

  1. 每种组合是一个新饮品, 类爆炸.
  2. 构造基类持有调料, 具体子类是饮料, 在子类构造函数中set调料. 还是有很多类. 但调价比较容易.
  3. 装饰者模式
    基础饮料 和 配料 实现相同的抽象
    配料 持有 基础饮料的对象
    配料中 实现 配料与基础饮料的混合

装饰者模式: 动态地将责任附加到对象上.
若要扩展功能, 装饰者提供了比继承更有弹性的替代方案. 避免继承滥用
实现要点:

  1. 装饰器内部持有被装饰者.
  2. 装饰器与被装饰者 有 共同的抽象.

缺点:

  1. 可能引入大量小类(装饰器), 最终组合过程复杂, 组合产生的对象很多. 所以一般结合 工厂模式 和 生成器模式
  2. 使用者 需要基于 共同的抽象 编程.

1.2.4 工厂模式

 
  1. 简单工厂

    问题场景: store(上层组件)使用多种pizza(下层组件)
    简单工厂:将所有new移到一个工厂中, 工厂返回抽象 设计原则 体现: 依赖倒置. 简单工厂已经体现依赖导致了

  2. 工厂方法模式

    问题场景: 需要不同工厂, 不同的store
    工厂方法模式:定义了一个创建对象的接口, 由子类实例化.
    将对象创建交给了子类.

    简单工厂使用工厂对象, 工厂方法模式提供工厂框架, 子类使用工厂对象.

1.3 TODO java与Lisp

 

posted @ 2021-04-01 01:21  董庆然  阅读(221)  评论(0编辑  收藏  举报