《head first 设计模式》学习心得(一)

来源:互联网 发布:健康体检报告软件 编辑:程序博客网 时间:2024/06/07 18:47

head first 设计模式这本书还是蛮贵的,不过对于初学软件设计的人来说值得一看。

大概看到一半的样子,把所能想到的写下来作为总结:

前面这八章讲了这么几个设计模式:

1. 策略模式:

这种模式的主要精神就是面向接口的编程。打个比方,我需要做菜,那么我有的是食材,需要的是一盘菜,那么我就定义一个父类,包含把食材变成菜的方法的声明,如果该声明为(c++ 版纯虚函数)abstract,那么意味着所有的子类都要重定义该方法。

那么在使用这个类的时候,可以把对象声明为父类,那么意味我可以用不同的子类去实例化它,我不管是如何把食材变成菜,我只知道但凡是子类,就可以做到这个。

这种模式给予了一个软件的框架的某个模块用不同方式实现的可能性。把容易变动的地方设计成像机械零件一样可以随时替换,而这些零件之所以可以随意替换,是因为它们都共用同样的接口。

那有人会问,如果我需要更换算法,直接把这个类重写一遍不就可以了,何必如此麻烦。

也对。

不过策略模式依然有被需要的时候。举一个实际的例子。比如写一个3D的渲染工具,像3dmax那样的,那么考虑到将来你可能打算通过多种方式来实现图像的渲染,那么渲染的算法应该独立于记录场景信息的类以及显示二维图像的类,写成一个接口,这样你可以延迟到运行时决定使用哪一种渲染算法,如此增加了软件的弹性。

策略模式的关键在于找到可能发生变动的模块,并把它们分离开来,通过接口联系在一起。

这样一种思想贯穿于整个OO的设计思路中,即我们希望当我需要改动程序的时候,我能够把这样的改动限制在一个可以接受的范围内。

策略模式的一种极端的做法是,把所有的类都写成接口,然后通过子类化去实现它。

这种做法的问题在于,打字打的非常多,而且通过父类调用子类方法往往需要更多的时间。

如何取舍,取决于你对将来变动可能性的把握,实际上已经超出了设计模式讨论的范围。

2. 观察者模式:

这个模式可以用一个比喻概括,即有一个报社,跟一堆各式各样的订报者,这些订报纸的人可能拿报纸做各种各样的事情,用来收藏,糊墙或者上厕所。

抽象来说,就是一个信息发布者和一群信息接收者的模式,一对多的关系。

简单的逻辑就是,一旦信息发布者发布了信息,它要负责通知每一个信息接收者:信息得到了更新。

根据信息接收者获取更新的方式的不同,观察者模式有两种方式来实现:

第一种的主动权在信息发布者手上:由信息发布者负责调用每一个信息接收者的update()函数,传入所有的数据,信息接收者则被动的更新。

而如果并不是每一个信息收集者都需要相同的信息(比如小明可能想看看明天有什么电影,而小红只是想知道明天要不要下雨),那么让信息接收者主动地获取它需要的信息是更好的方式。坏处就是,信息发布者要反复处理来自接收者的申请。对于稀疏的信息需求,这种方式更为合理。

3. 装饰模式:

个人来说,我最不喜欢这种设计风格。层层嵌套的包装模式让我觉得整个程序都是冗余的代码。思路挺复杂的,所以我简单说下好了。(我也不知道这句话的逻辑在哪里)

有一个基类,通常是一个虚基类,定义了某一个类所用到的一些方法。

然后子类化为一个具体的类。比如说,咖啡。

咖啡是一个可以被修饰的类,比如,可以加糖,可以加奶等等,因为这些修饰,咖啡的某些行为会发生一些改变。比如价格会高一些。

具体的实现方式需要一些小小的技巧。

首先子类化一个装饰者类,类中包含一个父类对象,HAS-A关系。

对于需要装饰的对象,直接把被装饰着放在这个类中的父类对象中,然后重写父类的方法即可。

值得一提的是,由于修饰类并不知道被修饰类的任何信息,因此弹性的代价是不能很好的管理这些类。

解决这个问题的一种方法是,写一个getDiscription()方法,返回一个可以叠加的数据类型,比如说字符串和动态数组。

这种模式有个很大的缺点,每增加一个装饰类,你必须要把所有的方法都重写一遍。因此这种模式在遇到方法很多的类的时候比较让人头疼。此外,无数个马甲也给管理马甲带来的困难。


原创粉丝点击