Posts tagged 设计模式

[好书第二弹]大话设计模式

大话设计模式封面

书名:《大话设计模式》

作者:程杰

出版社:清华大学出版社

书号:9787302162063

 

为什么要学习设计模式?

面向对象程序设计是现在的主流,但又有多少人真正地用面向对象的思想去开发程序?我经常在我用ActionScript写的几个类之间 复制/粘贴 代码,如果要修改程序的某个细节,我经常要修改很多地方,到后来还会发现,如果要添加某个新功能,还要修改之前写好的很多代码。总之,写出来的程序代码乱乱的,而且难以修改,如果几天不看,连自己都会忘掉那些类,那些方法,那些属性都是干嘛的……

这是很多面向对象程序设计的初学者都会遇到的问题,也是学习设计模式的理由。

在程序开发中使用设计模式并不能让你的程序身材更小,运行的更快,却能让你的代码更容易维护,扩展和重用,让你编程的效率提高,把你不得不将你写的程序全部返工的几率降到最小。

为什么要看这本书?明明有更经典的著作……

好吧,我知道你很厉害,你可以轻松地读懂那四人组1 的大部头著作,你可以轻松理解那23个设计模式到底是什么东西,可是并不是所有人都像你那么厉害。对于一个新手来说,那种高人写的“高书”可谓高深莫测,读起来很容易头晕肚子痛,最后放弃学习。所以,新手需要一本通俗易懂的书,而《大话设计模式》就是这样一本书。

《大话设计模式》的一大特点就是,通篇采用情景对话的形式,用小故事和编程实例来讲解四人组总结的23个设计模式。虽然我已经见识过让人读起来感觉好像在与朋友交流的《Head First HTML》,可是这本《大话设计模式》还是让我感到很新鲜——我实在是没有见过把编程技术放在故事里讲的书。

是的,即便实质还是在讲设计模式,但这20多个故事却起到了相当不一样的效果。书中的人物小菜,在大鸟的帮助下,从泡MM、拍UFO、吃羊肉串等事情中,渐渐地领悟了设计模式,并最终成为别人的引路者;阅读这本书的读者,也在这个过程中,不知不觉地受到小菜的影响,从而学到东西。

《大话设计模式》的另一大特点是突出演化。书中的每个故事里都会针对问题先给出一个解决方法,而这个做法通常就是我们常犯的错误(在书中,这个倒霉蛋就是小菜);然后,随着故事的发展,再给出正确的做法。读者会看到从“错误”到“正确”的演化,在对比中自然地加深对设计模式的印象。用作者的话说,这是要“授人以渔”,让读者真正地体会到这种演化之中的智慧。

总之,这是一本与经典著作全然不同的书,它适合那些第一次接触设计模式,或者曾经看过别的书却没有看懂的人。它并不能取代四人组的经典著作,也不能取代别的什么经典著作,但却可以作为阅读这些经典大餐的开胃菜。我很喜欢这本书,所以我也向你推荐。

  1. 设计模式的经典名著——Design Patterns: Elements of Reusable Object-Oriented Software,中译本名为《设计模式——可复用面向对象软件的基础》的四位作者Erich Gamma、Richard Helm、Ralph Johnson,以及John Vlissides,这四人常被称为Gang of Four,即四人组,简称GoF []

AS3:单例模式的大材小用

前言:临近期末了,有的课要考试了,不考试的课则要收作业了。这几天为我的个人网站做了一个FlashWeb,并且准备拿它交某门课的作业。这个FlashWeb的设计来源于Dreamix给我秀过的一个About页,那个页面用JS实现了非常酷的九宫格效果,而我用ActionScript 3(缩写为AS3)纯代码对其进行了模仿。我会整理一下我在做这个东西时用到的技巧,今天是第一篇:单例模式的大材小用。

今天的话题,要从数字说起。有编程经验的人都知道,在程序代码中不应该直接出现大量的特定的数字,因为数字没有明显的含义,容易使人产生困扰。为了避免这个问题,在使用C、C++、Delphi这些语言编程时,对于那些要经常使用但不需要改变的数字,常使用宏或常量来代替,并且将这些宏和常量的声明放在一些头文件(*.h)中,以便在别的程序中使用include来调用。最明显的例子就是MFC和VCL对Windows API里的一些常量的封装,你常常会看到一串大写的单词,而它们通常表示一串16进制的数值。想想吧,如果在编程的时候必须直接使用这些16进制值,将会是多么可怕的一件事。

可是在最新版本Flash和Flex里面采用ActionScript 3语言编程的时候,我们不能使用“include头文件”这样的方式,因为AS3采用了标准的面向对象编程模式。可是事情还是有解决的方法的。比如经常会用到的这句代码:

button.addEventListener(MouseEvent.CLICK, onMenuBtnClick)

Flash类库的这种设计不仅使代码的意义更清楚,还带来了另一个好处——开发工具(我用的是Flex Builder)可以为我们提供代码提示和自动完成,还会有严格的语义检查。那么MouseEvent.CLICK究竟是什么呢?让我来分析一下:
首先,圆点符号在AS3中通常是什么?是对类的属性和方法的访问。
那么,MouseEvent是什么?我猜它是一个类。
最后,CLICK是什么?我猜它是MouseEvent类的一个公有属性。
让我来验证一下吧。在Adobe官方的“ActionScript 3.0 语言和组件参考”中,对MouseEvent有如下描述:

包 flash.events
类 public class MouseEvent

好了,看来它确实是一个类。接着,在此文档中,有一个名为“公共 常量”的列表,第一项就是CLICK,这说明我完全猜对了。

现在回到我的FlashWeb。由于要模仿Dreamix给我的JS,我需要处理非常多的数字。这包括了颜色、位置(x,y)、大小(width,height)、运动参数(速度,缓动因子)等等一大堆的数字,而且我会在不止一个类里面使用它们。所以,向Flash的类库学习,就是我唯一的选择。
首先,我写了一个名叫numData的类,把我想得到的数字都放在里面,写成公共常量(public const),并给每个常量都起了一个有意义的名字,这样只要在别的类里建立一个numData的实例,就可以调用这些常量了。
看上去这样就可以了,是么?但是,等等!我使用MouseEvent的时候,并没有对其进行实例化(就是new MouseEvent()),就能直接使用它的常量!要实现这样的效果,就要使用static(静态)关键字,将其声明为静态常量,这样一来,即使不创建实例,也可以调用此常量了。
事实上,单例模式(Singleton Pattern)就是这样来的。有的时候我们不希望别人创建某个类的多个实例,而只允许这个类被实例化一次,所以我们会对外屏蔽类的构造函数,而只提供自定义的一个方法。Java程序员通常采用的办法是,把类的构造函数写成私有(private)的,然后提供一个静态公共方法来让别人访问类的实例。但是在AS3中,不允许私有的构造函数。这时大家常常通过抛出异常的方法来避免构造函数被外界执行,同时写一个静态方法来提供类的实例,其中的一个典型的写法,可以在RIAHome的文章《如何在ActionScript 3.0里使用单例模式》里看到。
很复杂是么?但是我需要单例模式么?暂时不需要。我现在只需要单纯地让我的numData类不会被任何人创建实例,所以我只需要将RIAHome介绍单例模式的文章中,禁止外界访问构造函数的部分拿来,就可以了。

package
{
    public class numData
    {
        static public const ...
        public function numData(enforcer:SingletonEnforcer){}
    }
}
class SingletonEnforcer {}

现在,我有了一个足够好的numData类,我可以享受Flex Builder的代码提示和错误检查带来的便捷,而且我的程序也更加清楚、有意义。

好了,今天要说的就是这些。

P.S. FlashWeb上线,放到 http://i.coolcfan.org 了
P.S.2 看来我应该装一个代码高亮的插件……可是哪个插件支持ActionScript 3呢?