这段时间看那本GoF的设计模式,主要是用c++描述示例的,故把一些c++知识点放在这里备忘。
作者:littlebat
GoF的《设计模式》之入门介绍
转载请注明本文原始出处:GoF设计模式之入门介绍: http://java.learndiary.com/diaries/3150.jsp。本文在原始出处随时更新,欢迎批评指正和讨论。
--JAVA学习日记 littlebat 2007.04.02 16:33
正文:
*********************************************************************
用了一周多时间把这章看了一遍,并结合其中的内容把自己原来记的学习Thinking in Patterns with Java的日记复习了一下,感觉对各种设计模式的印象又清楚了一些,提起某个模式的名字大概知道了是怎么一回事。下面记下学习这章中的一些知识点和心得如下:
要做一个好的设计是困难的,设计模式的作用就是把这些被反复证明了的好的设计以一个统一的形式归纳记录下来。一旦一个设计的“套路“被证明是有效的,就像一个“浪漫小说“那样有一套固定的模式,可以反复的套来用。GoF总结的设计模式只是那些专家们知道的一个片断,还有像分布式编程、实时编程、设备驱动编程、面向特定应用领域编程等等的设计模式还有待别人去归纳整理(littlebat注:不知道这些领域的设计模式现在有没有?情况如何?学习领域现在不知有没有设计模式?也许学习日记可以在这方面看一看)。
1、什么是设计模式?
(The design patterns in this book are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.)设计模式是在特定的环境中用来解决通用的设计问题的相互交流的对象和类。它的粒度不是细到讲怎么样实现一个链、一个哈希表,也不是粗到整个应用或者子系统。一个模式有4个基本元素:名称、解决的问题、解决的方案、结果。设计模式的实现的复杂程度跟选择的实现语言关系很大,所以有的设计模式在一种语言中实现起来很复杂,而在另一种语言中实现起来很简单,甚至有些模式已经被某种语言内置支持(littlebat注:像在Thinking in Patterns with Java中读到的那样,像Iterator, Observer, Adapter, Proxy等模式就在Java语言中内置支持,另外,Java中的clone()方法是否是prototype模式、Java的package是否是Facade模式、而Java的序列化技术是否是Memento的模式、Comparator是否是Strategy模式的内置支持还不是很清楚?)。这本书主要是采用C++(littlebat注:要复习一下c++语法了) 和 SmallTalk来实现例程。
2、Smalltalk MVC里的设计模式:
这一节分析了SmallTalk的MVC框架(littlebat注:Java中的Struts也是一种MVC实现)所涉及到的设计模式包括:Observer, Composite, Strategy, Factory method, Decorator等等。
3、描述设计模式:
这本书以一套固定的模版来描述一个设计模式,包括:名称和分类、目的、别名、动机(Motivation)、适用性、结构、参与的对象和类、参与者的交互、后果、实现、例程、已知的使用例子、相关模式。(littlebat注:其中为阐述结构,使用了现在UML的前身包含的一些技术,如OMT,交互图,序列图等等。。。我想,这些技术与UML应该差不多,有些区别通过看其它相关的内容也应该可以知道的。另外,UML好像是1997年才正式发布的?)
4、设计模式的目录:
这一节列出全部23种设计模式的目录和简短的描述,Abstract Factory (87), Adapter (139), Bridge (151),
Builder (97), Chain of Responsibility (223), Command (233), Composite (163), Decorator (175), Facade (185), Factory Method (107), Flyweight (195), Interpreter (243), Iterator (257), Mediator (273), Memento (283), Observer (293), Prototype (117), Proxy (207), Singleton (127), State (305), Strategy (315), Template Method (325), Visitor (331)。
组织目录:
GoF主要用两个标准来划分设计模式,一个标准是目的,分为:创建、结构、行为的目的。如下:
创建的目的:
Factory Method (107)
Abstract Factory (87)
Builder (97)
Prototype (117)
Singleton (127)
结构的目的:
Adapter (139)
Bridge (151)
Composite (163)
Decorator (175)
Facade (185)
Proxy (207)
行为的目的:
Interpreter (243)
Template Method (325)
Chain of Responsibility (223)
Command (233)
Iterator (257)
Mediator (273)
Memento (283)
Flyweight (195)
Observer (293)
State (305)
Strategy (315)
Visitor (331)
第二个分类的标准是模式使用的范围,包括:类的范围、对象的范围。如下:
类的范围:
Factory Method (107) Adapter (139) Interpreter (243) Template Method (325)
对象的范围:
Abstract Factory (87)
Builder (97)
Prototype (117)
Singleton (127)
Adapter (139)
Bridge (151)
Composite (163)
Decorator (175)
Facade (185)
Proxy (207)
Chain of Responsibility (223)
Command (233)
Iterator (257)
Mediator (273)
Memento (283)
Flyweight (195)
Observer (293)
State (305)
Strategy (315)
Visitor (331)
书中还提出了也有其它的方式来组织设计模式,如有的设计模式经常放在一起用,有的可以互换,有的设计结果的结构相似等等。并特别的提出了一种根据设计模式间的关系来组织目录的方式,这就是很重要的设计模式的关系图(Figure 1.1,我把这张图放在了后面的附图中:图1.1)。
(littlebat注:我觉得关系图中的关系主要是一种模式使用了另一种模式的关系,如:图中的Composite模式使用了Iterator模式来遍历子对象,Iterator使用了Memento来保存遍历的状态。
另外,在Thinking in Patterns with Java中的分类是根据设计模式解决问题的性质,我本来以为在GoF的设计模式中没有按问题分类,结果是GoF把这种分类放在了设计模式怎样解决设计问题的下一节中。
另外,我发现了一些现在看来在这两本书中有点矛盾的地方:如在Bruce先生的书中说Decorater模式是解决类太多的问题(Thinking in Patterns chapter 9: too many),Bridge模式主要在用于代码的组织上(Thinking in Patterns chapter 10: Connecting different types),而在GoF的书上把这两种模式都归为在对象范围内应用的模式。也许他们是从不同的角度来说的,还需要进一步学习。
)
5、设计模式怎样解决设计问题
这一节是这一章中内容最多也算最重要的一节吧。它讲了oop设计者可能面临的各种设计问题和设计模式怎样帮助设计者解决这些设计问题。这些设计问题如下:
1)、找出恰当的对象
2)、决定对象粒度
3)、指定对象接口
4)、指定对象实现
(1)类继承对接口继承
(2)编程到接口而不是实现
5)、使重用技术运用起来
(1)继承对组合
要更多的使用组合
(2)代理
(3)继承对参数化类型
取决于实现的系统
6)、关联运行时和编译时结构
7)、设计成适应改变的系统
在这一节中指出了一些系统不易改变(灵活性差,稍有扩展和改变引发代价较大的重新设计)的问题和针对相应问题的设计模式:
(1)精确的指定类来创建对象
Design patterns: Abstract Factory (87), Factory Method (107), Prototype (117).
(2)依赖特定的方法
Design patterns: Chain of Responsibility (223), Command (233).
(3)依赖硬件和软件平台
Design patterns: Abstract Factory (87), Bridge (151).
(4)依赖对象表现或实现
Design patterns: Abstract Factory (87), Bridge (151), Memento (283), Proxy (207).
(5)算法依赖
Design patterns: Builder (97), Iterator (257), Strategy (315), Template Method (325), Visitor (331).
(6)紧耦合
Design patterns: Abstract Factory (87), Bridge (151), Chain of Responsibility (223), Command (233), Facade (185), Mediator (273), Observer (293).
(7)用继承扩展功能
Design patterns: Bridge (151), Chain of Responsibility (223), Composite (163), Decorator (175), Observer (293), Strategy (315).
(8)不能方便的改变类
Design patterns: Adapter (139), Decorator (175), Visitor (331).
而对于这种改变灵活性的要求程度如何取决于所实现的系统,按灵活性要求从低到高分为3类系统:
(1)应用程序
(2)工具包
(3)框架
框架和模式的区别:
1>、设计模式更抽象
2>、设计模式是要小一些的结构元素
3>、设计模式更通用化一些
这一节可以同Bruce先生从解决问题对设计模式进行的分类比较着看,Bruce先生根据设计模式解决的问题分成:
1>、Object quantity: Singleton
2>、Object decoupling: Proxy, State, Iterator
3>、Factoring commonality: Strategy, Policy, Template method
4>、Encapsulating creation: Factory method, Abstract factory
5>、Specialized creation: Prototype, Builder
6>、Too many: Flyweight(too many objects), Decorator(too many classes)
7>、Connecting different types: Adapter, Bridge
8>、Flexible structure: Composite
9>、System decoupling: Observer, Mediator
10>、Reducing interface complexity: Facade
11>、Algorithmic partitioning: Command, Chain of responsibility
12>、Externalizing object state: Memento
13>、Complex interactions: Visitor
14>、Multiple languages: Interpreter
现在看来,好像Bruce先生的针对解决问题的分类的可操作性要简单易懂一些。我印象比较深刻的就是那个Too many,例如:如果我在一个设计对应于现实对象的静态结构中找出了过多的类(像Bruce先生举的那个咖啡馆里的咖啡种类),我可以第一时间想到:这么多的类是不是用Decorator减少一些哟?当然,我还没有真正的实践过设计模式,也许真到那时使用这些设计模式也不是这么一回事。先记在这里回头再说吧。
另外,在这一节中有一些东西需要更进一步的学习,如class和type的区别,UML和OMT的区别?怎样用设计模式解决问题?还有,这一节的内容很多,不少东西都是粗粗读过,还需要在读完全书后再回过头来反复读,正如作者说,这不是一本看完一遍就扔在一边的书。
6、怎样选择一个设计模式
1)、想想设计模式怎样解决设计问题的
2)、查一下设计模式的意图
3)、研究一下设计模式的相互关系
4)、研究一下目的类似的设计模式
5)、检查一下引起重新设计的原因
6)、考虑一下你的设计中的变化因素
下面是书中的一个表,列出3种目的的设计模式可以解决的系统中的变化因素,描述格式是:设计模式 设计中可能变化的方面
1>,Creational
Abstract Factory (87) families of product objects
Builder (97) how a composite object gets created
Factory Method (107) subclass of object that is instantiated
Prototype (117) class of object that is instantiated
Singleton (127) the sole instance of a class
2>,Structural
Adapter (139) interface to an object
Bridge (151) implementation of an object
Composite (163) structure and composition of an object
Decorator (175) responsibilities of an object without subclassing
Facade (185) interface to a subsystem
Flyweight (195) storage costs of objects
Proxy (207) how an object is accessed; its location
3>,Behavioral
Chain of Responsibility (223) object that can fulfill a request
Command (233) when and how a request is fulfilled
Interpreter (243) grammar and interpretation of a language
Iterator (257) how an aggregate's elements are accessed, traversed
Mediator (273) how and which objects interact with each other
Memento (283) what private information is stored outside an object, and when
Observer (293) number of objects that depend on another object; how the dependent objects stay up to date
State (305) states of an object
Strategy (315) an algorithm
Template Method (325) steps of an algorithm
Visitor (331) operations that can be applied to object(s) without changing their class(es)
7)、怎样使用一个设计模式
讲当你选择了一个设计模式后怎样使用它。
(1)把这个设计模式通读一遍
(2)研究结构、参与者、交互部分
(3)看例程部分
(4)为设计模式中的参与者选定名字
(5)定义类
(6)为设计模式中的方法(操作)定义具体到应用的名字
(7)实现模式中的方法
最后,这节讲了一个非常重要的观点,设计模式不能滥用,因为为达到灵活性等设计模式的使用常引入间接的附加的层次,这使系统变得复杂或(和)影响性能。只有设计模式提供的灵活性是系统真正需要的时候才使用它。后面的章节对评价一个设计模式的损益很有用。
*********************************************************************
附图:图1.1
计算机使用小技巧集锦
收集一些一两句话的计算机使用小技巧供备忘和交流。
在linux系统中备份远程mysql数据库的脚本文件2则
1、备份成rar的分卷压缩格式,生成两个(若有分卷的rar压缩文件会不止两个)备份文件,如:
db20070325092032.sql,db20070325092032.sql.rar
|
**********************************************************************
2、备份成*.tar.bz2的压缩格式,生成两个备份文件,如:
db20070325092032.sql,db20070325092032.sql.tar.bz2
|
一周回顾(2007.03.24)
孩子感冒生病打了两天针,可能还需要看一下医生;突然记起孩子好久没打预防针了;
上周把大部分时间都用在折腾这台486的老机器上,在一块硬盘上重新安装了windows97+redhat linux9.0;而既定的学习设计模式的目标好像在心里一点也不急,这样下去是不行的,猴年马月才把那本GoF的设计模式看得完。时间的利用要有重点,就好像金钱的使用要“用在刀刃上”一样。本来想在当当网上买一本GoF的设计模式,可一想没必要,用这个钱买了一块二手硬盘放在486的老机里。那块有坏道的1.6G的硬盘权当“移动硬盘”吧。
惨,昨天早上和老婆去跑步,没跑多远就觉得累,看老婆还比较轻松的样子;
今天早上和老婆到体育馆,我在单杠上做引体向上,做一个就不行了:(,原来读初中考体育引体向上的及格线是10个还是20个?
看来,我得锻炼一下了。
能在486+windows97上正常使用的opera游览器最新版
我的这台机器上是486DX100+24M+windows97,在上面安装的IE5.5在浏览有些网站时竟然不能使用,如在当当网上注册,登录google的广告帐号(有近一个月没有登录了:))... 我估计是IE5.5的https的支持上有问题。
然后我安装原来下载的firefox1.*,竟然不能安装上;
在google上以“最小的浏览器“为关键词搜索,结果是opera。在opera的官方网站上下了一个最新版的:opera9.1,在我的机器上的版本信息如下:
Version information
Version 9.10
Build 8679
Platform Win32
System Windows 95
Java Java not installed
XHTML+Voice Plug-in not loaded
Browser identification
Opera/9.10 (Windows 95; U; en)
我在google的广告帐户上和当当网上使用opera9.1均正常,虽然由于机器差速度慢,但毕竟可用。推荐那些在老机老系统上上网的朋友试一下opera浏览器。
GoF的《设计模式》之前言、序言和用户指导
从书的前言可知,GoF设计模式是那四个家伙在1994年8月完成的。这本书是给对面向对象设计有一些基本了解的朋友读的。使用设计模式的目的是为了使设计更加灵活、模块化、可重用、可理解。这本书不是那种读一遍就扔在一边的书,所以你不要因为你读一遍而不完全理解它们而担心,就是作者们自己在第一次写的时候也没有完全理解(littlebat注:所以说,把心得和疑惑诉诸文字的过程也是理解和深化的学习过程,这也是我写学习日记的主要因素之一,还有一个主要因素是备忘等等)!这是一本值得反复阅读的书。这本书从酝酿到完成用了很多时间,书的四个作者来自四个国家,并且得到了许多人的帮助和支持(littlebat注:有两大段鸣谢的人名)。这本书只是反应了作者当时对设计的一种思考的记录,必将随着时间的推进而不断发展(littlebat 注:从我在网上看到的的情况来看确实如此,各种语言的设计模式版本出现,各种新的设计模式应该也在发明中,可以说有许多人在用设计模式吃饭,你看看太多的相关书籍就知道了,不过我觉得GoF的设计模式才是它们被公认的源头,所以我就想试着读读这本书的英文电子版了,有必要的话再去买一本英文版的或翻译版纸质书)。
从CD的前言可知,CD版(电子版)的书是在应许多人的反馈于书发行后3年的1997年发行的。CD版的书可以使查阅和使用更方便。这篇前言也总结了他们的书发行3年来的巨大成功,确实达成了他们当初的心愿:使更多的软件工程师从中获益。同样,这篇前言鸣谢了对CD版发行有帮助的人。(littlebat注:这个CD版的好是好,只不过用了javascript和java applet小程序技术,让我在486的古董机在linux控制台下w3m浏览器中无法阅读,特地为读这本书装了一个windows97,当初他们就没有考虑过有人在控制台下读这本书吧。不过,也知足了,况且我目前还是盗版用户呢。)
然后是Rational的那个OOP方面的大腕Grady Booch给他们作的序,开头绕了一大段计算机考古专家考查计算机历史“地层”的话,让我看不懂。他的序的意思就是:GoF的设计模式很成功,能从他们那里学到很多,他们的贡献可以在计算机的发展历史上记上一笔了。哦,这里提到那四个家伙的名字:Erich, Richard, Ralph, and John(littlebat注:好像有个家伙现在已经不在人世了,“四人帮”变成“三人帮”了)。
下面这篇用户指南值得好好读一读,它先是讲了一下这本书分为两大部分:第一部分(第1、2章)是基本概念和案例,第二部分(3、4、5章)是具体的分为3类的23种设计模式;然后它给了你几种阅读23种设计模式的方式,你可以根据自己的实际情况选择一下。这几种方式大概包括:
1、从头到尾依次阅读;
2、顺着设计模式之间的关系读(有一个关系图:Figure 1.1 (page 12) );
3、可以按所着手解决的问题的分类来读(Section 1.6 (page 24) );
3.5、或者先通读,再按工程中要解决的问题来应用这些模式;(与上是同一段说的)
4、如果你对OO不是很熟的话,可以从几个最简单和通用的模式开始读,这些模式包括:
* Abstract Factory (page 87)
* Adapter (139)
* Composite (163)
* Decorator (175)
* Factory Method (107)
* Observer (293)
* Strategy (315)
* Template Method (325)
我暂时选择的阅读方式是上面的3.5的方式,先通读,并对比我在Thinking in Patterns with Java读到的相应的设计模式,以后如果写程序的话再按解决问题的分类“按图索骥”。
孩子给爸爸倒茶,还要给妈妈倒洗脚水
大概有几周时间了吧,孩子常常很有兴趣的给我把茶杯里放上茶叶,然后叫别人把茶杯里倒上水,然后端给我,说:“爸爸请喝茶。”不管是孩子的一时的兴趣还是什么别的因素(例如幼儿园里的教育),我都是很高兴的。不过,就是有一点,她要是要给我泡茶,我不喝还不行,不管什么时候,非接受不可:),弄得我还认真的跟她说:“爸爸想喝茶时再给爸爸泡茶好吗?”
不知是什么时候起,电视里有了公益广告;也不知是什么时候起,有了那个小孩子看到妈妈给婆婆洗脚然后自己也去端水给妈妈洗脚的公益广告。我们的孩子看了那个公益广告后,对我和她妈妈说她也要给我们端水洗脚。当然,我们没让她给我们端水洗脚,孩子是很喜欢玩水的,说不定到时候我们还没开始洗,她自己玩水就把衣袖打湿了。也许哪天她再提起这事,也应该让她试试,我想这是没有坏处的。另外,可见周围环境(尤其包括电视)的引导对孩子是比较重要的。
实际上,孩子是家里的“小霸王”,比如,她有什么事叫我们,往往是这样的口气:“爸爸,过来!”。我也不会多想,往往就屁颠屁颠的跑过去,听孩子 “吩咐”。我觉得,这对形成家里的平等和民主的氛围有好处;当然,教育孩子说话懂礼貌也是应该注意的,那么,是不是要给孩子说说对人说话不要用这种“命令式”的语气呢?
棉签+酒精+润滑油修复软驱和VCD机
不知是什么时候起,机器上的软驱不能工作了,读软盘时报告磁盘未格式化,真去格式化时又报告不能格式化;一会儿又报告设备没有准备好。
在网上查了一下。打开软驱看它读盘,磁头小车根本不动。偶尔能够读盘时发现磁头动了几下。按网上介绍的用医用棉签醮着高纯度酒精把可能受灰尘影响的地方都擦了一下,重点擦了上下两个读写头。没有看到网上说的发光二极管和三极管,一个好像叫微动开关的检测是否有盘的东西在固定软盘的地方看到了。
然后把磁头小车旁的传动螺杆上的原来的脏的润滑油擦掉,滴了几滴润滑油(我用的是变压油),再把螺杆转了几圈。软驱就又可以工作了。
到现在我也不知道究竟是哪个零件出了毛病,也许是原来传动螺杆上的润滑油太脏了吧,也许。。。
想起家里那台罢了工的VCD机,“死马当成活马医”,粗暴的打开机壳,结果大多数的塑料卡子都被我弄坏了,不过没有大碍。拆开后看里面就几块简单的电路板。用棉签醮酒精把激光头擦了几下。VCD机又可以工作了。
再介绍两个小技巧:
1、如果你的电子辞典之类的东西的按键里面的导电橡胶失效了,可以把香烟盒里的锡箔纸用速干502胶水粘在导电橡胶上,注意能够导电的锡箔那边是朝外的。
2、如果你的电冰箱的冷藏室里的化冰排水孔堵了,可以用给自行车加气的打气筒从排水孔下方的出水口往上打气就行了。
删除linux的/tmp目录引起的不能正常登录系统的故障
昨天无意查看到/tmp目录竟占了400M的空间,看到里面全是一个乱七八糟的东西。联想到windows的temp目录的作用。就把/tmp目录删除了,想系统启动时可能就重新建了这个目录。结果系统只能启动到控制台模式;
又用mkdir /tmp建了这个目录,结果系统在控制台模式登录和X windows模式登录状态间反复切换,不能进入系统;
后来在网上查了一下,改变了/tmp目录的权限为:chmod a+rwx,o+t /tmp,即为:
drwxrwxrwt 4 root root 4096 3月 16 10:18 tmp
系统恢复正常。
具体分析原因如下:
正常情况下,/tmp目录的权限是:
drwxrwxrwt 4 root root 4096 3月 16 10:18 tmp
它表示所有的用户都可以在其中建立文件(或目录),即任何人都对tmp目录拥有“写权限”,但是除非tmp目录的所有者和文件的所有者,其他人不能在/tmp目录下改写(或删除、重命名)别人的文件(或目录)。
如果你删除了系统的tmp目录,又用mkdir /tmp建立这个目录,那么根据umask的规定,默认建议的目录的权限是:
drwxr-xr-x 3 root root 4096 3月 16 11:31 tmp
那么其他人就不能在/tmp目录下建立文件了;这时,系统将出现故障(如:不能启动或不能进入x windows);
如果你用:chmod a+w /tmp改变/tmp目录的权限为:
drwxrwxrwx 3 root root 4096 3月 16 11:34 tmp
那么任何人都可以删除别人在/tmp目录下的文件了,包括删除root在/tmp目录下建立的文件;
如果用:chmod o+t /tmp为/tmp目录加了粘滞位t,那么其他人就不能在tmp目录下改写(或删除、重命名)别人的文件(或目录),起到了/tmp目录的作用。
另外,“suid”和“sgid”特殊标志位可以使普通用户运行一个程序,使这个程序访问或修改只有文件所有者或root用户才能直接访问或修改的文件,当然前提是这个普通用户对这个文件的某个部分拥有相应的权限。
详情见转帖:linux的权限和所有权模型(转帖): http://java.learndiary.com/diaries/3110.jsp
本人的系统是redhat linux9.0+amd duron 700。在网上查到有人说删除某些linux发行版本的/tmp目录下的文件会使系统不能正常工作,也不知道是不是真的。不过,这次也再一次给我一个教训,对linux操作系统不熟悉的地方不能按照windows的模式想当然的操作。尤其是系统是正式的工作系统,应该坚持“宁滥勿缺”的原则,不要想当然的删除你不熟悉的文件或目录。