设计引导---设计模式基础

新手阅读Gof的《设计模式》有点难度,这里,要讲述的是,帮助大家奠定一下基础,使大家更好的去学习设计模式,去提升我们的思想,设计包含着抽象,又有些哲学,静下心来,你也可以学到优秀程序员的技术。

设计模式,起初是从建筑学中开始发展的。在此来讲个故事。

很久很久以前~~~(^_^),有一个建筑师,他修建了许多建筑,当地的人都十分尊敬他,因为他修建的房屋,是最牢固最美观的,但是他自己一直在问自己:“质量可以客观评价吗?”这位建筑师最感兴趣的一种美就是建筑质量:是什么让我感觉一个建筑设计是优秀的?

   

    “评价一个建筑物是否美观”不仅仅是一个品味的问题。还需要通过可以衡量的客观标准来描述美观程度,比如质量,创意什么的。

    我们软件的构建,也如同建筑学一样。需要设计,需要规划,它们有太多的相似的地方了。

    我们也可以试着问自己:

        优秀设计能表现而劣质设计不能表现什么?

        劣质设计能表现而优秀设计不能表现的又是什么?

    嗨!是否很矛盾呢?

    没关系,故事还没讲完,建筑师观察了许多的建筑,城镇,街道,以及人们的生活环境。他发现,对于任何特定的建筑物,优秀的结构之间,总有一些相同之处。

    建筑结构不相同,他们类型相同,尽管如此,他们仍是高质量的。

    比如说我们每天使用的电脑,新产品的型号不同,但是他们终究是电脑,他们既然要销售,电脑就必须是高质量的。(你见过劣质电脑,能打铺天盖地的广告吗?)

    建筑师通过这样的方式,观察解决相似问题的不同解决方案,一步步缩小他的关注焦点,他可以洞察出优质设计之间的相似之处,并把这些相似之处称为”模式”。

    聪明的建筑师,把模式定义为“在某一个情景下的问题解决方案”。

    每个模式,通过一种让你可以无数次使用这一解决方案、而不必再次重复同样的工作方式,描述一个在我们环境中重复出现的问题,并描述该问题解决方案的核心。

    用简单的例子来描述一下这个有点复杂的概念:

        建筑师需要修建一个庭院

        然后建筑师就会对于这个庭院有自己的构思:庭院可以享受阳光,享受星辰,要有私有的户外空间,需要些花花草草,有条件修建个小水池也不错。

        然后建筑师,再向庭院主人详细问下个人的独特需求,然后建筑师就能开工

在这里,建筑师的思考过程,就是我们所提到的模式,模式它有一个名称,在这里就是个庭院模式。然后他有个目的:帮助人们在其中生活。

    为什么说这个庭院是一个优秀的庭院?建筑师修建了许许多多的庭院,他知道什么样的庭院才是适合人们的,符合人们习惯的,他有经验。然后它可以复用自己的经验,优秀的建筑师所设计的,一定是美的。

经验,可以使人们少走弯路,借鉴经验,从而加速达成目的。

模式几乎存在所有的设计问题中。

每个模式描述,都由下面4个组成部分:

  • 模式的名称
  • 模式的目的,它要解决的问题
  • 我们如何实现它
  • 为了实现它我们必须考虑的限制和约束

建筑师有一颗追求美的心。

 

好啦^_^,故事讲完啦,我们回到正题,软件设计模式。

“四人组”的《设计模式》是一部经典之作,很经典。

也许你都看过这本书了,知道这里面收录了23个模式。

在这需要认识到的是:

    这几位作者并不是书中这些模式的创建者。几位作者识别除了那些已经存在于软件社群中的模式,“从特定问题的优质设计中学到的经验”。

任何一个模式描述都需要包括下面的基本要素:

名称 每个模式都有一个独一无二名称,人们用名称来鉴别模式
意图
模式的目的
问题 模式视图解决的问题
解决方案 对于自己出现的场景中的问题,模式怎样提供一个解决方案
参与者和协作者
模式包括的实体
效果 使用模式的效果,使用模式的同时研究其约束
实现 怎样实现模式。实现只是模式的具体表现形式。
Gof参考 在四人组的书中得到更多信息的位置

现在大家应该知道什么是设计模式了吧?现在再来完成一个大家疑惑的问题。

为什么要学习它们?

我们知道,学习写模块化的软件,能使软件复用

现在要让大家知道,学习设计模式,能够复用解决方案,通过复用已经建立的设计,能为自己遇到的问题找到更高的起点,并避免了绕弯路。

受益于学习别人的经验。不必再为普通、重复的问题重新设计解决方案。有没用听起来很热血澎湃的感觉?最起码我是如此,代码重用不厉害,思想重用才厉害^_^。

第二点:

建立通用的术语,在交流于协作时,都需要一个共同的词汇基础、一个对问题的共同观点。设计模式在项目的分析和设计阶段提供了一个通用的参考点。

第三点:

对于问题、设计过程和面向对象,模式给你一个更高的层次的视角。你能从过早处理细节的通病中解放出来。(别以为处理细节不严重,繁琐的细节,让我崩溃,深有感触T-T)

不好理解这一点? 没关系,看个简单的模拟场景:

假设有两个木匠正在讨论如何为橱柜制作抽屉的问题。

木匠1:”你认为我们应该怎样制作这些抽屉呢?“

木匠2:“我想我们应该这样做结合部分,在木材上直锯下去,然后回转45°锯,然后再直锯下去,再朝另一个方向回转45°锯,再....然后......”(他在扯细节问题!!)

现在,你的的工作就是弄明白他们究竟在说些什么!看看分解之后的:

这里有些夸大了,真正的木匠师傅,并不会真的在细节的层次上说话,他们会用专业术语。

木匠1:我们应该用一个燕尾接合还是一个斜面接合?

这就是上面说的,建立通用术语,然后在高层次讲述问题。假如让你选择和他们其中一个人合作,你会选择谁?

模式能让我们同时看到树木和森林。

第四点:

学习设计模式,最重要的原因:它,能改表你的思想,让你成为更有力的分析者。

第五点:

它能提高你的效率,头脑思考的效率。别人是单核,而你是双核,这多么爽呀?

五点足够让你很有成就感了,其实好处不仅仅只有这些。

 

当在团队中,设计模式既可以帮助单个开发者学习,也可以帮助团队开发。这是因为,团队中的低级成员看到懂得设计模式的高级开发者从模式中获益,于是这些低级成员也想得到这些好处,这为他们学习这概念提供了有理的动机。

    大多数设计模式还让软件更具可修改性,需求永远都在变,能适应变换的设计模式,让维护软件成为一种轻松的工作,还有什么理由不去学习?

我们知道,底层建筑决定高层建筑,在某种程度上,高层建筑能也能反馈底层建筑更多的信息。

  在设计模式被正确传授时,可以大大增加学习者对基本面向对象设计原则的理解。(对于这一点,我是深有感触)在我学习设计模式时,使用它们来说明基本面向对象概念(封装、继承、多态等)在你学习了一些设计模式之后,即使你并不直接使用设计模式,你也会在自己的设计问题中使用这些策略。

    设计模式还有一个优点,能让你或你的Team可以为不需要巨大继承体系的复杂问题创建设计方案。

    总结:

    学习这些可以帮助你:

  • 复用现有的、高质量的、针对常见的重复出现问题的解决方案。
  • 建立通用的术语,改善团队内部的沟通。
  • 将思考转移到更高的视角。
  • 判断是否拥有正确的设计,而不仅仅是一个可以运行的设计。
  • 改善个人学习和团队学习。
  • 改善代码的可修改性。
  • 促进对改良设计的选用,升值在没有明确使用模式的时候。
  • 发现“庞大的继承体系”的替代方案。

(吐血,下面又是第二写!!!自动保存个又坑我。以后再也不拿这个网页写随笔!愤怒

好处差不多讲完了,现在来看些能够提高理解设计模式的具体方法。

has-a关系和is-a关系:

为什么要讲这个关系?园子里其实有人已经讲过这两个关系。我觉得这两个关系本该通俗易懂的,用简单的例子里整合一下,免得新手再去找相关关系去理解,太麻烦。(知道此关系的可以跳过此处,看看下面的UML介绍^_^)

has-a关系:

一个类“包含”另一个类。

一个简单的比喻就是,汽车他就是一个has-a的关系,汽车由各种配件组成,方向盘,发动机,轮胎等。

使用组合的可以把简单的东西组合成一个系统。组合就意味着可替换,一部分坏了,你可以选择修,也可以选择换。换好之后意味着,整个系统依旧良好的运行。

组合还有个优点,使用组合可以独立创建系统和子系统,更重要的是可以独立的进行测试和维护。(我深知其中好处,各种复用啊)

组合有两种类型,一种是关联(也叫组合,为了区别一下,我用关联),一种聚合。

关联:汽车就是关联,它由各个组件组合而成。

聚合:轮胎就是个很好的例子。

is-a关系:

“是一个”关系。看看图:

dogUML图可能大家还没熟悉,下面我也会简单介绍一下,帮助大家打下阅读UML图的基础。

在这里我可以说:狗是一种动物,代码表示就如下

Dog D=new Dog();

Mammal M = D;

这没错,狗和头有关系,但我们不能这么写:

Dog D = new Dog();

Head H = D;

这明显是错的,狗有头,但有头的不一定是狗,它可以是别的。比如猫。

在这个图的关系中,我们还可以给狗命名,就好像这样写:

Dog D = new Dog();

Nameable N = D;

它运行的很好,也很自然,一个名字代表一条狗。

在这个关系图中,我们用到了继承和接口。

我们知道,能继承的不仅是基类,它也可以是接口。

继承和接口都是构成is-a关系的简单而有效的证据。啰嗦一点,接口其实也有个关系在里面:

    can-do关系:看一个接口的时候,主要看它能做什么。例如:一个类型能将自己的实例转换为另一个类型(IConvertible),用过Framework 提供的接口的同学,更能体会。

组合和继承是创建类的主要形式。

包含往往比继承更可取,除非你要对“is-a“关系建模。

继承是一种有用的工具,但它却会增加复杂度,复杂度是软件管理的首要杀手。

UML基本语法注解:

方法内"+"表示Public,“-”表示Private,还有一个“#”这里没有提到,表示Protected,它很少用到。

在方法后面,还有一些setName:void和getName:String只代表这个方法的返回类型。

括号内的就是参数列表。

这张图我们要关注的就是那个空心箭头,它表示继承金毛猎犬继承于狗类。

这个就关注空心棱形。它表示组合,方向盘是汽车的一部分。

这个也简单。连接线就是代表关联,客户端和服务端就是关联的,再看一张前面介绍过的图:

dog

虚线三角箭头代表继承自接口,而接口的描述方式就是箭头指向的样子interface。

 

使用UML来辅助设计非常有用,这里简单的介绍是为了让大家更能看懂设计模式的类图说明,UML的完整讲述就需要一本书了。

尽管UML重要,但学习OO技能更为重要,先学习OO的基础概念,才能看懂UML图。

 

图是辅助,辅助大脑更好的思考。

但这里提议的是:

无论你用什么例子,都应该把注意力放在OO概念上。

 好了,基础就讲述这么多了,愿大家在设计模式的学的轻松^_^

posted @ 2013-01-21 09:35    阅读(2488)  评论(12编辑  收藏  举报