Java多线程编程实战指南:设计模式篇(第2版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.1 设计模式及其作用

设计模式(Design Pattern)是软件设计中给定背景(Context)下普遍存在的问题的一般性、可复用的解决方案[1]。这个定义可能有点抽象,但是我们可以先了解一下设计模式的历史由来以对其获得一个感性的认识。

一般认为模式(Pattern)起源于Christopher Alexander所提出的建筑上的概念,后来有人开始将其用到软件行业。这其中最为人所熟知的是Erich Gamma等4人(这4人亦被称为Gang of Four,GOF)于1994年所出版的经典之作《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)。实际上,国人也不必舍近求远,我们可以从大家耳熟能详的三十六计中去直接感受一下设计模式是什么。

中国古代兵法著作《三十六计》中提到的许多计策都是大家耳熟能详的,例如调虎离山计、离间计、反间计等。《三十六计》中的每个计策都可以看作一个关于计策的模式。例如,其中的借刀杀人计的描述如下:

敌已明,友未定,引友杀敌,不自出力,以《损》推演。

意思是说,目前的形势是,谁是敌人已经明朗而谁是友人尚未明确。在此情形下,利用“友人”去消灭敌人,自己则不用亲自动手便能够坐收渔人之利。这个计策是根据《易经》中的损卦推演出来的。

借刀杀人计的描述就可以反映出设计模式的几个要素。首先是所谓的给定背景,它指明了什么情况下可以运用某个计策(模式)。借刀杀人计中的“敌已明,友未定”(谁是敌人已明朗,谁是友人尚未明确)就说明了该计策(模式)的运用背景。其次是解决方案,当然解决方案的背后是问题。对于借刀杀人计而言,要解决的问题很明显是消灭敌人,而相应的解决方案是借他人(即“友人”)之手而不必自己亲自动手:由于敌人已明朗,而“友人”尚未明确,借“友人”之手去消灭敌人,则这两方无论谁受打击对己方而言都是有利而无害的。再次是隐藏在计策(模式)背后的思想,《三十六计》中的计策源自《易经》中的卦象(思想)。例如,借刀杀人计就是根据《易经》中的第41卦(损卦)推演出来的。

另外,计策和计策之间往往不是孤立的,而是需要相互配合使用的。例如,离间计(其核心是破坏敌人内部关系,使他们疏远)和反间计(其核心是发现敌方的间谍后不揭穿而利用其传递假情报)就经常配合着使用。《三国演义》中“蒋干盗书”的故事就是综合使用了离间计和反间计以削弱曹操的势力。赤壁大战前夕,曹操手下的谋士蒋干去东吴劝降周瑜,周瑜则故意在书房中让蒋干盗得一封捏造的由曹操水军将领蔡瑁、张允写给自己的降书,以利用蒋干携带假情报给曹操,离间曹操与蔡瑁、张允之间的关系。曹操果真上了当,斩了精通水战的蔡瑁、张允。另外,三十六计中专门有一计叫作连环计,其核心就是环环相扣地使用其他各个计策。连环计更加明确地表明了各个计策之间不是孤立的,在特定情况下它们是相互联系的。

此时回到正题,就不难理解设计模式了:我们可以将设计模式看作软件设计领域的三十六计。

正如三十六计中的各个计策之间并不是孤立的,而是相互联系的,设计模式与设计模式之间也不是孤立的。在解决实际问题的过程中,我们往往需要综合使用多个设计模式,而不是单靠某个设计模式,这点从本书后续所提供的各个实战案例中可见一斑。

隐藏在三十六计背后的是《易经》中的思想,而隐藏在设计模式背后的是面向对象设计的思想[2]

设计模式是一种可复用的设计方案,它并不是可以直接使用的代码。因此,这就涉及设计模式的实现问题,即如何将设计方案转化为可执行的代码。当然,这也涉及编程语言,具体来说是面向对象的编程语言。因此,一方面设计模式依赖于编程语言,因为最终我们要将设计模式转化为具体的可执行的代码;另一方面,设计模式具有语言独立性,一个设计模式可以使用Java语言实现,也可以使用C++、C#等其他面向对象的编程语言实现。当然,在实现设计模式时我们也必须考虑所选用的编程语言自身的特点。由于本书选用Java语言作为实现语言,因此对设计模式进行描述时有时会直接从语言的层面出发。读者若需要以其他语言作为实现语言也无妨,只要在具体实现时充分考虑语言自身的特点即可。考虑到设计模式本身并非可直接使用的代码,而其实现又离不开代码,本书在介绍各个具体设计模式的时候会尽可能地给出相应的可复用实现代码,以便读者理解和应用相应的设计模式。

设计模式可以为我们解决设计问题提供可借鉴的成熟解决方案。设计模式是在广泛实践的基础上提炼出来的设计方案。这也就意味着,很多设计模式已经被广泛运用在很多软件的设计之中。例如,Java标准库API的设计就运用了很多设计模式。本书也正是鉴于此,在介绍每个具体的设计模式时,设有专门的一节介绍Java标准库对相应设计模式的运用。

设计模式为软件开发人员之间阐述和沟通设计方案提供了公用的词汇。在团队开发中,软件的设计必然涉及设计方案的讨论与沟通。一方面,负责设计的人员之间需要进行方案的沟通。另一方面,最终负责落实设计方案的人员(开发人员)也需要理解设计方案,这当然也涉及相应的阐述和沟通,而设计模式为开发人员之间阐述和沟通设计方案提供了一个统一的基础,即大家都能理解且理解一致的词汇。这种词汇在软件设计过程中所起的作用,正如其他专业术语(如继承、多态等)在我们工作的过程中所起的作用一样。比如,团队成员在讨论一个关于如何扩展我们手头没有源代码的Java类的问题时,有人提出“我们自己新建一个类,该类继承自××类”,此时大家便都明白可以怎么做了。

设计模式可以作为描述软件架构的一种方式。设计模式构建了开发人员之间阐述和沟通设计方案的词汇,因此它自然可以用来描述软件的架构。有了设计模式,我们在描述系统架构的时候便可以使用“本模块运用了××设计模式”之类的语句。