设计形式之《松本行弘的程序世界》的读书笔记
设计模式之《松本行弘的程序世界》的读书笔记
<在Evernote写笔记,直接从Evernote中复制出来,格式有所偏差>
《松本行弘的程序世界》http://book.51cto.com/art/201108/284603.htm
设计模式原本是从面向对象的代码中总结出来的,但是现在的编程语言往往在语法级别就封装了一些常用的设计模式支持。
设计模式和具体编程语言无关,但是设计模式在各个具体语言里面的使用方法不尽相同。
面向对象的软件开发中有很多普遍存在的原则(Principle),在设计以及开发面向对象程序的时候,就应该遵循以下抽象原则:
- 开放-封闭原则(OCP)
- 单一职责原则(SRP)
- Liskov替换原则(LSP)
- 依存关系倒置原则(DIP)
- 接口隔离原则(ISP)
- 迪米特法则(LoD)
- 合成/聚合复用原则(Composite/Aggregate Reuse Principle . CARP)
我们的目标是使代码符合上面的这些原则,这是目的。我们如何达到这个目的呢?那就是使用设计模式,这是手段。目的比手段更抽象,也即原则比设计模式抽象程度更高。
设计模式可以分成3大类:有关生成的模式(5个),有关构造的模式(7个),有关行为的模式(11个)。
1. Singleton 单例模式 (生成)
说明:保证某个类的实例只有一个
为什么:系统全体只需要唯一一个这个对象
如何做:
- 使用库的方法实现
- 使用类或者模块
- 把一般对象作为单例,重写new方法等等手段,这是一般语言常用的方法
总结:反正不管用什么手段,必须只有一个实例!必须的!
2. Proxy 模式 (构造)
说明:为某个对象提供代理对象。 什么意思?为什么:如何做:
- 不想把实现写死,调用程序只和Proxy打交道
- 延迟加载具体程序,先加载Proxy
- 屏蔽具体实现的复杂性,简化调用接口
- 库
- 自己写代码(库其实也是别人写的代码)
3. Iterator 模式 (行为)
说明:提供按顺序访问集合对象中各元素的方法,即使不知道对象的内部构造也可以按顺序访问其中的每个元素。为什么:为什么?如何做:
- 类库只带实现,例如java里面的集合类,都是可迭代的,不过调用代码写起来比较拖沓
- 语法自然实现,python里面就自然的实现,例如 for x in XXX.
- 你自己写代码实现
总结:这已经是最基本的东西了,几乎都不算是个模式了。在有闭包的语言ruby,内部迭代器。没有闭包java,外部迭代器。
内部迭代器的缺陷:不能同时进行多个循环,也就无法实现按顺序比较2个集合元素的处理。所以返回外部迭代器也有它的优势!比较优秀的是内外部无缝集成。感觉上Ruby偏向于内部迭代,Python更偏向于语法级别的自然外部迭代。
外部迭代器的缺陷:外部迭代器的缺陷在于迭代器(光标)对象需要参照集合对象的内部信息。为了按顺序访问集合对象的各个元素,迭代器对象需要访问集合的内部构造,这就破坏了隐蔽集合内部构造的封装性原则。
4.Prototype
(单词解释the first example of something, such as a machine or other industrial product, from which all later forms are developed)
说明: 明确一个实例最为要生成对象的种类原型,通过复制该实例来生成新的对象。静态类型语言往往发挥不出这个模式的作用,在动态类型语言里面才能发挥它的巨大威力。甚至于 Prototype模式应该称之为编程范式(Paradigm)更合适。例如大部分编程语言从编程范式上来说都是类模式,但是JavaScript就是一种原型模式,JavaScript不直接定于类,然后由类来生成对象,而是直接复制对象,然后往对象上添加属性和方法变成新的对象。为什么:自然而然如何做:1. 编程范式级别 2.语法级
5. Template Method 模板方法 (为了编写抽象算法的模式)
说明:在父类的一个方法中定义算法的框架,其中几个步骤的具体内容则留给子类来实现。
为什么:1. 可以在不改变算法构造的前提下,在子类中定义算法的一些步骤。
6. Observer 模式 (避免高度依赖)
说明:当某个对象的状态发生变化时,依存于该状态的全部对象都自动(被动)得到通知,而且为了让他们都得到更新,定义了 对象间的一对多的依存关系。这是控制类与类之间依存关系的一种模式。
7. Strategy 模式
说明:定义算法的集合,将各算法封装,使它们能够交换。