序
距上次写博客已经有好些日子了。前些日子里,我不仅读完了《大话设计模式》我还读完了一本非专业书籍,黄灯写的《我的二本学生》。笔者黄灯以一名大学老师和辅导员的视角,回顾了从70年代到90后二本学生境遇的变迁,反思了一些现实性的问题。
读完颇有感悟,有时间的话我希望可以单独为此写篇读后感。但现在就先让我总结我在《大话设计模式》一书中学到的内容吧。
迭代器模式
本文以公交车售票员一个个挨着查票的故事为例(这本书年代久远啊,现在苏州这公交车都已经采用无人售票很多年了),引出了迭代器模式的大致思路:
迭代器模式提供一个方法,用于顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
总之,当你需要访问一个聚集对象,你只想要遍历他,而不用管这些对象是什么时候,你就该考虑使用迭代器模式。
其实读到这里,我第一个想法就是Python中的很多数据结构实际上就是迭代器模式思想的体现,例如遍历一个list,它和c++不一样之处在于C++是通过递增序号实现的,而Python更本不用暴露序号只要写:
# Python Code
for item in itemList:
# do somethig like printing items
print(item)
而c++是这样实现的,C++数组一般要传入序号i:
//Cpp Code
int a[5] = { 1, 2, 3, 4, 5};
for(int i = 0; i < len(a); i++)
{
//do something like printing.
print(a[i]);
}
说白了,这就一历史问题。文中也指出:“现在来看迭代器模式使用价值远不如学习价值大了,MartinFlower甚至在自己的网站上提出撤销这个模式,因为现在的高级编程语言例如C#、JAVA等本身已经把这个模式写在编程语言之中了。......但研究历史是为了更好的迎接未来。”(原书P202)
单例模式
在书中使用MDI窗体重复出现的问题引出“Form1中应该只是通知工具箱,至于工具箱窗体是否实例化过,应该由工具箱自己来判断”为例,引出了单例模式。
他的想法是让对应的类去处理实例化问题,而不是在客户端上处理实例化。给出的具体定义如下:
单例模式保证一个类只有一个实例,并提供一个访问他的全局访问点。
结构图如下:
具体实现方法是,将构造函数设定为private,接着写构造窗口的代码,构造窗口的代码封装了构造函数,在调用构造函数的时候判断下窗体是否被构造过了。
桥接模式与聚合复用原则
本节举的例子是游戏编程时候,可能会有手机版(这里举的例子是诺基亚的塞班系统,哈哈哈)和PC版两个版本,但是有时候功能函数都是一样的,为了代码复用,引出了“合成/聚合复用原则”。
文中指出:“对象的继承关系在编译时就确定,运行时是无法改变从父类继承来的实例。子类的实例与父类有紧密的依赖关系。所以你想复用子类时,继承下来的实现不适合解决新问题,就必然需要改动父类,这样极大得制约了灵活性。”
这里有几个概念:聚合表示一种弱的拥有关系,即A可以包含B,但B不一定要是A得一部分(隐含之意是,B可以是A得一部分(包含关系),也可以是交叉关系或者说组合关系)。
合成则是一种强的拥有关系,即严格的部分与整体关系(只有包含关系),部分与整体的生命周期是一致的。
然后引出合成/聚合复用原则:
尽量使用聚合,而不是类继承。
接着就是讲桥接模式了,先给出了定义:
桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立变化。
抽象与实现分离是指抽象类和它的派生类用来实现各自的对象,抽象类与派生类是无法分离的。结构图如下:
最后书中在P233页指出:很多设计模式其实就是原则的应用,在不知不觉中可能就会被你使用到。