我给媳妇解释设计模式:第一部分

来源:互联网 发布:nodejs npm安装linux 编辑:程序博客网 时间:2024/04/27 22:46

英文原文:How I explained Design Patterns to my wife: Part 1

引子

我跟媳妇曾经就面向对象设计这个话题做过有趣的探讨。当我把它们发表在社区之后,得到了一些很不错的反馈,也大大鼓舞了我。所以,我很高兴能把我们后面的一次谈话继续分享出来,那是关于面向对象的设计模式的,大家往下看吧。

什么是设计模式

丈夫:我想你现在对面向对象的设计原则有了一些基本概念了吧。我们那次关于OOD原则(SOLID原则)的有趣谈话被我发表在社区上了,你不会介意吧?网址在这里:我怎么向妻子解释OOD

设计模式则是这些原则在某些特定和常用条件下的应用,并且做了一些标准化。我们还是来一些例子吧。

媳妇:好极了,我喜欢例子。

丈夫:以我们的车为例吧。它是一个对象,不过有点复杂,是由几千个其它对象组成的,包括引擎、车轮、转向装置、座位、车身,等等。

一辆车的各种零件。这辆车在制造的时候,制造商收集所有的零件,把它们组装起来。这些零件本身也是复杂的对象,是由其它的制造商组装的。但汽车公司并不关心这些零件是怎么造出来的(当然,他们需要确信这些零件的质量是过硬的)。他们只会关心如何通过不同的方式将不同的零件组装起来,以便生产出不同型号的汽车。

由不同零件根据不同设计组装成的不同型号的车。

媳妇:每种型号的汽车应该都有各自的设计和蓝图什么的,是吧?

丈夫:非常正确。而且,这些设计是经过深思熟虑的,花了很长的时间和很大的努力才得以诞生。完成设计之后,汽车的生产就只剩下遵循设计这么简单的事了。

媳妇:嗯……很不错的办法,先想出一些优秀的设计,然后遵照这些设计,就可以在很短的时间里造出不同的东西。如果制造商想要开发某种型号的产品,不需要从头进行设计,或者说重新造轮子,只要遵循那些设计就可以了。

用于不同型号产品(车)的不同设计。

丈夫:你说到点子上了。现在,回到现实里,我们是软件厂商,我们需要根据需求,用不同的组件来创造出不同的软件。在这个过程中,一定会碰到一些情形,是在许多不同的软件里都有的,对不对?

媳妇:对啊。而且,我们还常常在不同的软件里碰到相同的设计难题呢。

丈夫: 我们尝试着用一种面向对象的方式来开发我们的软件,利用OOD原则来让我们的代码更容易管理、重用和扩展。就像你上面提到的那些相同的问题,如果我们预先就有一些良好的设计,那是不是很棒呢?

媳妇: 是啊,那可以省下大把的时间,而且这样打造的软件质量更好,更容易管理。

丈夫: 没错。还有个好消息,我们并不需要自己造轮子。这么多年以来,遭遇同样问题的人们早已发现了许多很棒的解决方案,而且把它们标准化过了。我们管这些方案叫设计模式。

我们要感谢四人帮(GoF),他们在设计模式: 可重用面向对象软件的基本元素这本书里归纳了23个最基本的设计模式。想知道这四个牛人是谁吗?Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides。面向对象的设计模式很多,但大家认为这23个模式是其它模式的基础。

媳妇:我能创建一个新模式吗?有可能吗?

丈夫:当然可以,亲爱的,为什么不行呢?设计模式并不是被科学家发明和创造的东西。他们只是被“发现”而已。也就是说,对任何一个普通的问题场景,肯定会有一些好的设计方案。如果我们能识别出一个能解决某个新问题的面向对象设计,那我们就定义了一个新的设计模式。谁知道呢?如果我们发现一些设计模式,没准儿大家会叫我们“二人帮”呢...哈哈。

媳妇::)

我们怎么来学习设计模式呢?

丈夫:我始终坚信,通过例子学习是最好的。在我们的学习过程中,我们不会“先理论后实践”,因为我认为这是一种“坏”方法。设计模式不是基于理论发明的。相反,总是先有问题场景,再基于需求和情景不断演化设计方案,最后把一些方案标准化成“模式”。所以,我们讨论每一个设计模式时,要尽量用生活中的真实问题来理解和分析。然后尝试一步步地阐述设计,并以一个能匹配某些模式的设计收尾。设计模式就是这样被发现的,你觉得呢?

媳妇: 我觉得对我来说,这种方式可能更好使。如果我能通过先分析问题,然后阐述解决方案, 最后得到一个设计模式,我就不用死记那些图形和定义了。就这么办吧。

基础的设计问题和解决方案

丈夫:让我们考虑一下下面的情况:

我们的家里都有家用电器(比如电灯和风扇),他们都是由开关控制。任何时候,你都可以在不改变其他东西的情况下做一些事。你可以在不更换开关的情况下换掉灯泡,也可以在不接触灯泡或者风扇的情况下更换开关,甚至可以在不接触开关的情况下,把灯泡和风扇的开关互换。

家用电器:风扇和灯泡

两种开关(第二个显然比第一个要好看)

媳妇:对啊,这看起来很自然,不是吗?

丈夫:是的,非常自然,同时也应该这样安排。当不同的事物联系到一起时,他们应该在一个可以变更或者可以替换的系统中以便不相互影响,或者影响尽可能的小。这样让你更为方便、成本最小地去管理你的系统。可以想象,如果你要换一个你房间里的灯泡得要求你把开关也换了,你会考虑在你房子里使用这样的一个系统吗?

媳妇:当然不会。

丈夫:现在,让我们想一下电灯或者电风扇是怎样和开关联系起来以便更换其中一个而不会影响到其他的。你想到什么了?

媳妇:当然是电线啦。

丈夫:正确,是电线以及其他的电工手段把电灯/电风扇与开关连接起来。我们可以把这概括为沟通不同系统的桥梁。基本思想是,一个事物不能直接连接另一个事物。当然,他们能够通过一些桥梁或接口连接起来。在软件世界里,我们称之为“松耦合”。

媳妇:嗯,我明白这点。

丈夫:现在,我们来尝试理解一些类似电灯/电风扇与开关类似的关键问题,同时尝试理解是怎样设计和关联它们的。

媳妇:好的,我们开始吧。

在我们的列子里,有一些开关,这些类似普通的开关、有不同的花式开关可能有不同的种类,但是,一般情况下,他们就是开关。同时,每个开关都能开和关。

这样的话,我们就会得到如下的Switch基类:

原创粉丝点击