zoukankan      html  css  js  c++  java
  • 《软件设计精要与模式》前言

    缘起

    用过去几年互联网上最酷,而在当下已经被用滥的名词来说,我在2004年成为了一名博客,用日志的方式记录自己成长的经历。坦白说,技术的成长远远比身体的发育更加地艰辛与缓慢,尤其是当今信息爆炸的年代,我们担忧的不是吃不饱,而是应该怎么吃,吃什么?营养不良固然令人堪忧,营养过剩却也不是健康之道。如果我们对软件技术做一次全方位的扫描,收获地无疑是面对岔路口的彷徨与迷茫,就像博尔赫斯笔下的曲径分岔的花园。

    这是一种梦魇,就像在我的儿童时代,每次发高烧都会做的同一个恶梦一样,跑不掉,挣不脱,惊醒之后却又说不清的感觉。没人愿意走迷宫,除了那些以解谜题为乐趣的天才们。所以,我们在软件设计的迷宫门前停住了脚步;然后,四处顾盼寻找通过迷宫的地图。

    不知道世界上是否真的存在穿过软件设计迷宫的地图,但至少有人曾经通过,并且留下了淡淡的足迹。这些足迹或者交互重叠,或者纷繁杂乱,分不清哪里才是走过的正确的路。于是,寻找、识别与尝试就成为我们面对技术更新的时候要经历的三部曲。

    经典的技术,特别是经典的设计思想,完全可以免去这几个步骤。例如设计模式,在面向对象世界里,它已经成为了经典的存在,我们不必浪费时间去质疑它的重要性。省去了寻找、识别与尝试的过程,我们可以直接将它设定为亟待攻克的堡垒。正是基于这样的目标,我开始尝试与广大博友分享我的战斗攻略与心得。

    博客的风格是“童言无忌”,所以我能够自由写意地耕耘博客园的一块田地。俗语云:种瓜得瓜,种豆得豆。我种下了技术的种子,吸收着评论的养料,最后收获的却是现在这本呈现在读者面前的《软件设计精要与模式》,连我自己也要感到莫名惊诧了。书的出版缘起偶然。在我做完了一个长达一年多的项目之后,又参加了另外一个大型项目最后阶段的开发与测试,最后拒绝了一个周期可能长达几年的项目安排,结束了在北京的漂泊回到故乡。我开始了悠闲自得的放假生涯。一次偶然与博客园站长杜勇先生的闲谈,结束了我的休假状态,开始了数月的写书生涯。对于杜勇先生,我想把感谢的话放在本文的末尾,此时只想表达我的“愤慨”,是你,谋杀了我的闲适生活:)

    好在我这本书成不了指引人们走出迷宫的地图,所以我可以“没有责任心”地回过头来欣赏自己在迷宫墙上的涂鸦,即使是一个人的艺术,对于自己而言,也是一种美。萨特说:“存在即合理”,我相信本书能够体现这种逻辑的合理性。

    本书有些什么

    既然本书的内容源自于博客的内容,就必然继承了一些散漫自由的风格。我甚至建议读者把书中各章看作是一篇篇技术随笔,因为我实在厌倦了那种捧着高文大册时的战战兢兢了。于是,我努力在营造一种华丽的风格,以此来冲击那些习惯了枯燥与平实的读者口味。

    散文的要旨是“形散而神不散”,本书基本符合散文的精神。虽然每一章都可以看作是一个独立的部分,然而其中蕴含的思想却是一致的,因而又可以合为一个整体。如果观察整体的局部,我们又可以将其割裂开来,成为一个单独存在的系列。如此安排,固然与博客的风格有关,却能够兼得一个好处,就是读者可以有选择的根据自身情况进行阅读,而不必囿于整部书的约束。

    全书围绕着软件设计的核心内容,结合大量的实例与代码,使其告别了纯理论研究的空泛,将软件设计理论与项目实践完美地结合起来。遵循这样的原则,是因为我们在设计现实的软件,而不是在乌托邦中空想。软件开发,根本就没有乌托邦的乐园。

    根据表述内容的不同,全书以渐进但绝非进阶的形式分成了五大篇章。第一篇为“设计之要”,相当于是本书的总纲,列举了软件设计的要素,包括设计模式、重构、测试驱动开发、极限编程等。从涵盖面来看,“设计之要”一篇包容了软件设计中最重要的“流行元素”,它们是程序员向设计师“涅磐”的基石,是从小工到专家的修炼法门。受篇幅所限,我在阐述这些重要的设计要素时,只能是浅尝辄止,颇有几分意犹未尽的感觉。然而,我并不希望自己的论述浮于表面,而是希望能够结合具体的实例,深入浅出的解析它们的本质与精神。我希望读者在阅读完这些章节之后,有一种饥饿的感觉,不停地叩问与质疑,然后再“上穷碧落下黄泉”地去搜寻相关的资料,以求获得更加深入的理解。

    在第二篇“.NET Framework与设计模式”中,我偷懒地从.NET Framework的现有设计中寻找到有关设计模式的实践,包括Factory Method模式、Composite模式、Decorator模式、Iterator模式与Strategy模式。为了帮助读者更好地理解这些模式,在每一章中,我都采用了“抛砖引玉”的方式,首先分析相关模式的实质,并结合具体实例详解模式的目的与应用场景。最后,.NET Framework粉墨登场,尽显自己主角的魅力。由于.NET Framework是一个庞大的框架,包含的代码浩如烟海,不可能在短短的一章中穷尽其详细的设计。因而,我在引入.NET Framework实例时,力求简洁,删去了与文章主旨无关的代码,并辅以UML图体现设计思想。对于.NET Framework在实现相关模式时独具匠心的一面,我则不遗余力地给于详尽的介绍,力求深入透彻。

    .NET Framework是一道主食大餐,虽然美味可口,却未免有几分油腻。所以我在第三篇中又上了一道清炒时蔬,希望能够压一压油荤。“媒体播放器的设计之旅”一篇,引入了一个虚构的媒体播放器项目。之所以称为“设计之旅”,是因为媒体播放器的最后完善,确实是一段艰难的征程,设置重重路障的是为我们提供需求的客户。本篇的独有之处是各章既相互独立,又有着藕断丝连的联系。虽然是项目实践,但无疑更带了几分对相关设计模式探讨与研究的意味。本篇论述的设计模式包括Factory Method模式、Adapter模式、Decorator模式与Visitor模式。

    或许第四篇“设计模式应用实践”最能体现本书的价值。它仍然是设计模式项目实践的延续,凸现其价值的原因在于这些项目实践,均是我亲自参与设计与开发的项目。无疑,它们的实现更具有现实的指导意义。我常常在想,究竟是什么阻碍了程序员对设计模式的理解?他们的普遍意见是不患设计模式之艰深难懂,而患设计模式运用之困难重重。怎么将设计模式运用到实际的项目开发中,是他们面对的最大问题。所谓“读书百遍,其义自现”,我想,唯一的解决之道就是实践,实践,再实践。西方有谚语说“Practice make perfect”,翻译为中文就是“熟能生巧”。然而,盲目的实践终归是不成的,我们需要向他们展示一些已经实现了的示例。在对设计模式进行讲解时,我们固然需要示例的精巧、生动与形象,但最重要的特质还是要与实际的开发结合,否则,再贴切的示例都会成为“空中楼阁”。如果仅仅追求比喻的“一鸣惊人”,或许能够加深程序员对设计模式的理解,但对于如何在项目开发中实际运用它们,仍然是一片茫然。本篇论述的设计模式包括Abstract Factory模式、Builder模式、Command模式、Chain Of Responsibility模式、Observer模式、Proxy模式、Strategy模式、Template Method模式以及Bridge模式。

    第五篇“.NET体系架构设计”不再围绕设计模式,而是以更高地层次来叙述体系架构设计的诸多模式与原则。有关架构设计的分析最容易流于空泛,而本篇则以PetShop电子商务系统作为体系架构分析的示例,使得内容能够秉承本书一直坚持的项目实践准则。囿于本人所识,本篇无法对体系架构设计的方方面面作出全局的描述,主要介绍了分层式架构设计思想,并论述了相关模式的运用。其中,论述的设计模式包括Abstract Factory模式、Strategy模式、Facade模式、Proxy模式;企业应用架构模式中的Data Mapper模式、Domain Model模式、Page Controller模式以及MVC模式。

    本书面对的读者

    本书并非一本软件设计的入门指导,对于程序设计的初学者,本书的内容未免艰深了些。虽然我一直力求讲解浅显明白,试图以最简单的话与最清晰的逻辑阐述设计思想,并佐以丰富的实例展现设计的现实一面;然而,内容的自身特质决定了它不可能成为“从入门到精通”的大百科式全书。

    对于一名即将迈入软件设计门槛,或者有强烈渴求希望提高自身设计能力的程序员而言,本书或许能够满足你的这种诉求。假定你已经具备了一定的面向对象设计思想,且具备设计模式的基本知识,那么本书就不会拒你于千里之外了。如果你已经成为了一名合格的软件设计师,那么本书能够带给你的价值,更多的是参考与借鉴的意义。向优秀的软件设计师进发,是一条荆棘之路,本书或许能够磨利你的刀刃,助你披荆斩棘。

    王国维在《人间词话》一书中写到:古今之成大事业大学问者,必经过三种境界。“昨夜西风凋碧树,独上高楼,望尽天涯路。”此第一境界也。“衣带渐宽终不悔,为伊消得人憔悴。”此第二境界也。“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”此第三境界也。当你正在“独上高楼,望尽天涯路”的时候,本书或许能够帮助你迈入“衣带渐宽终不悔”的境界。

    本书的示例代码都以C#完成。然而本书并非程序语言的教学书,它关注的核心是软件设计思想,因此,略去语法本身所带来的不快,对于.NET平台下的其他语言编程人员,依然具有一定价值。本书关注于.NET平台技术,但并不排斥Java世界。实际上,除去.NET独有的技术以及运行环境,两者之间在软件设计思想上并没有什么不同。

    阅读前的准备

    本书提供了大量的示例。为了更好地理解本书,阅读代码并运行这些实例是非常必要的。因此,你需要准备好正确的软件环境。首先是.NET Framework 2.0,以及Visual Studio 2005。由于部分示例采用了测试驱动开发的模式,引入了单元测试代码,所以你需要下载并安装NUnit 2.0,下载地址是http://www.nunit.org/

    本书第五篇以PetShop 4.0作为体系架构设计的分析案例,因此,你有必要安装PetShop 4.0版本,下载地址为http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/bdasamppet4.asp。此外,你还需要安装SQL Server或者Oracle,因为PetShop需要访问数据库。实际上,数据库的设计也是软件体系架构设计中的重要一环。

    如何阅读本书

    你可以顺序地阅读本书,虽然“设计之要”一篇涵盖的内容可能会制造一些阅读上的困难,但它可以帮助你确立软件设计的基本思想与原则。然而,鉴于书中各章近似于“松散耦合”的关系,你也可以根据阅读兴趣选择相关的章节。事实上,本书并没有强迫性的阅读定式,你甚至可以像阅读博客文章或者技术随笔那样,带着轻松的心情浏览全书。

    如果你只对设计模式感兴趣,那么我希望你首先阅读第2章,它会告诉你设计模式最核心的思想——“封装变化”。几乎可以这样说,全书中有关设计模式的章节,都是围绕着“封装变化”的思想来阐述与实现的。

    如果你对面向对象设计思想还有些许疑虑,我建议你首先阅读第11章,然后,跟随着媒体播放器的设计之旅,到达你期望的设计目标。如果你受困于设计模式的项目运用,那么直接阅读第二篇与第四篇,会是一个不错的选择。如果你只是希望深入了解某一种设计模式,那么就看看目录吧,然后根据章节名直奔主题,或许可以为你节约宝贵的时间。

    关于重构、测试驱动开发与极限编程,你可以在第一篇中找到对应的章节。但如果希望全面的了解它们,那么还是抛开本书吧,它并不是你真正想要的。但如果你愿意认真地阅读第1章,或许它可以为你部分地解决有关软件设计的疑惑。

    如果你希望了解体系架构设计方面的内容,毋庸置疑,第五篇才是你需要关注的内容。但如果你希望扎实地走好软件设计之路,千万不要好高骛远,还是从第1章开始阅读吧。

    致谢

    除了被致谢的人之外,这一节内容往往被读者忽略,以至于漠视了所有支持我、帮助我的家人与朋友。所以,我希望将这一部分变得更有价值一些。为了不背离本书的核心精神,我引入设计的原则来阐述。
    致谢的方式有很多种,例如口头致谢,为对方献上鲜花或者赠送礼金,这相当于一种致谢策略。从软件设计的角度来看,我们可以定义如下接口:
    public interface IAcknowledge
    {
     void Acknowledge();
    }

    如果要实现口头致谢,可以定义如下的类,并实现IAcknowledge接口:
    public class Appreciation:IAcknowledge
    {
     public void Acknowledge()
     {
      Console.WriteLine("Thank you!");
     }
    }

    献花与赠送礼金的实现则如下所示:
    public class PresentFlowers:IAcknowledge
    {
    public void Acknowledge()
     {
      Console.WriteLine("To present flowers.");
     }
    }
    public class Reward:IAcknowledge
    {
    public void Acknowledge()
     {
      Console.WriteLine("Reward payment.");
     }
    }

    以上是典型的Strategy模式的实现,我们可以在文本文件中列出需要致谢的人,并给出致谢方式所对应的程序集名与具体类名。在读取了文本文件中的每一行值后,利用反射技术创建实现了IAcknowledge接口的具体类对象,然后调用Acknowledge方法,向对方致以我最诚挚的谢意。

    然而,致谢并不仅仅是单纯的某一种方式,我可能希望向妻子口头表示感谢的同时,献上一束新采的鲜花。此时,Decorator模式就可以派上大用场。如何实现呢?我们可以在阅读了第8章与第13章后,再回过头来思考这个命题。

    用生活的例子来阐述软件设计的原理,是吕震宇先生给与我的启迪。他的设计模式随笔系列向我展示了另外一种叙述的魅力。在我撰写本书期间,每当我的设计思路出现了纠缠不清的困惑,我会尝试去阅读他的文章,希望能得到一些启示。我必须感谢徐宁(idior)先生,他对于问题的探讨总有一种近乎于偏执的狂热,在与他的讨论中,我受益良多。卿子成先生曾经为本书提供了一些项目实例,虽然最后因为种种原因没有能够引入,使得本书失色不少,但他给与的帮助使我一直心怀感激。

    最不能忽略的一个重要人物是杜勇先生。可以说,没有杜勇先生,这本书根本就没有机会能够面世。最重要的是,在博客园安家的这几年时间,使我有机会结识更多在技术上志同道合的朋友。博客园促进了我技术的成长,作为博客园站长的杜勇先生居功至伟。感谢你给我以及数万博客园居民带来的免费的优质服务。

    必须感谢博客园出书团队成员,李会军(Terry Lee),徐宁(idior),Dflying Chen,Allen Lee,……你们的热情给了我极大的鼓舞。还要感谢双鱼座,你对本书的书名提出了中肯的意见。感谢Anders 小明,使我确定了本书的书名。特别感谢许多一直关注本书进展的网友们,你们的褒奖我愧不敢当,你们的批评我虚心接受。

    一本书的出版,绝不仅仅是作者付出辛苦的劳动就能实现的,幕后工作者的名字不应该被埋没。感谢博文视点的编辑与审阅者,他(她)们包括:
    责任编辑胡辛征先生
    编辑葛娜女士
    (注:大部分编辑名字现在未知,此处略)

    我想借这个机会感谢我的家人。父母生我养我,他们的恩情我即使是衔草结环也难以回报。对于本书,他们倾注了大量的心血,保障了我的后勤。特别是没有父亲每日的催促,本书不可能如期完稿。感谢我新婚的妻子,在我忙碌于写书的时候,总是忽略了你默默在我身边。即使是在阳光明媚的秋日,我也无法陪伴你去南山郊游。但你没有丝毫怨言,反而常常在我夜深写稿的时候,悄悄地给我端上一杯温暖的茶水。家人的关怀始终是这么温暖,我希望能将本书献给我亲爱的家人!

  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/wayfarer/p/609229.html
Copyright © 2011-2022 走看看