Head Frist 设计模式 by Freeman E.

Head First Design Patterns

Head Frist学习原则

  1. 慢一点,你理解的越多,需要记的就越少。
  2. 勤做练习,自己记笔记。
  3. There are no dumb Questions。
  4. 上床睡觉之前不要再看别的书了,或者至少不再看其他有难度的东西。
  5. 要喝水,而且要多喝水。
  6. 大声说出来。
  7. 听听你大脑怎么说。
  8. 要有点感觉!
  9. 设计一些东西!

为什么需要设计模式

  1. 知道OO基础,并不足以让你设计出良好的OO系统。
  2. 良好的OO设计必须具备可复用、可扩展、可维护三个特性。
  3. 模式可以让我们建造出具有良好OO设计质量的系统。
  4. 模式被认为是经过验证的OO设计经验。
  5. 模式不是代码,而是针对设计问题的通用解决方案。你可以把它们应用到特定的应用中。
  6. 模式不是被发明,而是被发现。
  7. 大多数的模式和原则着眼于软件变化的主题。
  8. 大多数的模式都允许系统局部变化独立于其他部分。
  9. 我们常把系统中变化的部分抽出来封装。
  10. 模式让开发人员之间有共享的语言,能够最大化沟通的价值。

OO基础

  1. 抽象(Abstract)
  2. 封装(Encapsulate)
  3. 多态(Polymorphic)
  4. 继承(Inheritance)

OO设计原则

单一职责原则(Single Responsibility Priciple)

一个类应该只有一个职责。

开闭原则(Open/Closed Priciple)

类应该对扩展开放,对修改关闭。Open to extension and closed to modifcaiton.

遵循开放-关闭原则通常会引入新的抽象层次,增加代码的复杂度。我们要把注意力几种在设计中最有可能改变的地方来应用开闭原则。

里氏代换原则(Liskov Substitution Priciple)

一个可以接受基类对象的地方必然可以接受一个子类对象。

接口隔离原则(Interface Segregation Priciple)

使用多个专门接口来取代一个统一的接口。

依赖倒置原则(Dependence Inversion Principle)

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

针对接口编程,不针对实现编程(Program to interface, not an implementation)

封装变化(Encapsulate what varies)

合成复用原则(Composite Reuse Principle)

多用组合,少用继承(Composition Favor over inheritance)

为交互对象之间的松耦合设计而努力(loose coupling)

最少知识原则(Least Knowledge Principle)

又称为迪米特法则(Law of Demeter)

只和你的密友谈话。

好莱坞原则(Hollywood Principle)

别调用我们,我们会调用你。(Dont’t call us, we will call you.)

将决策权放在高层模块中,以便决定如何以及何时调用低层模块。

与架构模式、框架、模块的对比

参考一线架构师实践指南
设计模式,相比架构模式应用面更狭窄,针对于特定场景;相比与框架活着模块,更抽象。框架、模块本身也会用到设计模式。

设计模式

策略模式

定义

策略模式(Strategy Pattern)定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

  • 设计原则:多用组合,少用继承; 封装变化;针对接口编程,不针对实现编程。

  • IS-A:继承 ; HAS-A/Implements:组合

实现

strategy pattern in ruby

UML

观察者模式

定义

观察者模式(Observer Pattern)在对象之间定义一对多依赖,当一个对象的状态改变时,它的所有依赖者都会收到通知并自动更新。

  • 设计原则 :松耦合;好莱坞原则。

  • 观察者可观察者(主题)之间用松耦合方式结合(loose coupling),可观察者不知道观察者的细节,只知道观察者实现了观察者接口。

  • 使用观察者模式,可以从观察者处推(push)或者拉(pull)数据。

  • 有多个观察者时,不可以依赖特定的通知次序。

实现

observer pattern in ruby

UML

常见场景

GUI框架里的按键等组件,注册不同的观察者到组件的不同类型事件上(如按键按下)。

装饰者模式

定义

装饰者模式(Decorator/Wrapper Pattern)动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

  • 设计原则 :类应对扩展开放,对修改关闭。

  • 装饰者和被装饰者对象有相同的超类,这里利用继承来达到“类型匹配”,而不是用继承来获得“行为”。

  • 可以用一个或多个装饰着包装一个对象。

  • 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为。

  • 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。

  • 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

  • 装饰者将一个对象包装起来以增加新的行为和责任;适配器将一个对象包装起来以改变其接口;外观将一群对象“包装”起来以简化接口。

  • 相关模式:适配器,外观模式

实现

decorator pattern in ruby

UML

工厂方法模式

定义

工厂方法模式(Factory Method Pattern)定义了创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

  • 设计原则 :要依赖抽象,不要依赖具体类;好莱坞原则。

实现

UML

抽象工厂模式

定义

抽象工厂模式(Abstract Factory Pattern)提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

实现

UML

单件模式

定义

单件模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。

  • 在JAVA中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
  • 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程问题(我们必须认定所有的程序都是多线程的)。

实现

singleton pattern in ruby

UML

常见场景

共享资源管理,如线程池(thread pool)、缓存池(cache)、注册表设置(registry setting)。

命令模式

定义

命令模式(Command Pattern)将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

  • 设计原则 :松耦合。
  • 在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接受者和一个或一组动作。
  • 调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用。
  • 调用者可以接受命令当作参数,甚至在运行时动态地进行。
  • 命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态。
  • 宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持撤销。
  • 实际操作时,很常见使用“聪明”命令对象,也就是直接实现了请求,而不是将工作委托给接收者。

实现

UML

常见场景

队列请求(日程安排,线程池,工作队列等),日志请求,事务系统。

适配器模式

定义

适配器模式(Adapter Pattern)将一个类的接口,转换成客户期望的另一个接口。适配器让原来接口不兼容的类可以合作无间。

  • 当使用一个现有的类而其接口并不符合你的需求时,就使用适配器。

  • 适配器改变接口以符合客户的期望。

  • 实现一个适配器可能需要一番功夫,也可能不费功夫,视目标接口的大小与复杂度而定。

  • 适配器有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。

  • 适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;外观将一群对象“包装”起来以简化接口。

  • 相关模式:外观模式装饰者模式

实现

UML

常见场景

外观模式

定义

外观模式(Facade Pattern)提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

  • 设计原则 :最少知识原则。
  • 当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。
  • 外观将客户从一个复杂的子系统中解耦。
  • 实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。
  • 外观将一群对象“包装”起来以简化接口;适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;
  • 相关模式:适配器模式装饰者模式

实现

UML

常见场景

模板方法模式

定义

模板方法模式(Template Method Pattern)在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

  • 设计原则 :好莱坞原则。
  • 模板方法是一种重要的代码复用技巧。
  • 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
  • 钩子是一种方法,它在抽象类中不做事,活着只做默认的事情,子类可以选择要不要取覆盖它。
  • 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
  • 工厂方法是模板方法的一个特殊版本。

实现

UML

常见场景

Reference:

  1. strategy pattern in ruby
  2. 单例模式的八种写法比较
  3. Evaluating Alternative Decorator Implementations In Ruby