设计模式前言与策略模式(strategy)

本文为学习记录,编写blog作为复习也方便以后查阅

设计模式在很多同学的脑海中是一个比较抽象的概念,有的童鞋认为学会了设计模式,是系统架构师不可缺少的必备知识,有得童鞋认为设计模式是成为大牛的必备条件,而更多的童鞋认为设计模式是自己的逼格提升的必要技能,对此,我只能呵呵咯,因为每个人的想法不径相同,不能强人所难。不过既然学习设计模式,那么大家的终点肯定是一致的~好吧···开头就扯了这么多废话。

切正题:

设计模式是什么?

模式被认为是历经验证的OO设计经验模式不是代码,而是针对设计问题的通用解决方案(说白了就是一种 duangduang 的思维方式)

我们为什么需要学习设计模式?

如大家所知,我们现在开发程序大多使用别人设计好的库与框架。我们讨论框架,利用他们的API写出我们需要的程序。享受别人代码所带来的duang~ 但是······这些设计duang~duang的框架无法帮助我们将应用组织成为容易了解、容易维护、具有弹性的架构。所以需要设计模式。有些童鞋可能会说:我OO基础 ok,逻辑思维 very good,设计良好的OO系统so easy。但是这些都不足以让你设计出良好的OO系统,良好的OO设计必须兼备复用、可扩充、可维护三个特性,而模式可以做到这些。

我们如何使用设计模式?

设计模式不会直接进入你的代码中,而是 先进入你的“大脑” 。一旦你现在脑海中装入了许多关于模式的知识,就能够开始在新设计中采用他们,并当你的旧代码变得稀烂一团的热干面的时候,可以利用他们重构旧代码。

库和框架是设计模式么?

库和框架提供了我们某些特定的实现,让我们的代码可以轻易地引用,但是这并不是设计模式,有时候,库和框架本身用到了设计模式,这样很好,因为一旦我们了解了设计模式,那么我们会更加容易了解这些库和框架的内部构造。简而言之,了解了设计模式,会方便我们去读懂大神们写出来的框架源码

其实学习设计模式还能增加沟通能力,众所周知:程序员的沟通能力直接影响到我们在职场中的发展。假如你的同事这时候来问你某一个模块是如何设计的?而你这样回答他:“我建立了这个广播类。它能够追踪所有的倾听对象,而且任何时候只要有新的数据进来,就会通知每个倾听者。最吊的是。倾听者可以随时加入此广播,甚至可以随时退出。这样的设计方式相当动态和松耦合…”。扯了这么多,比唐僧还沙悟净。如果我们都够了解模式,你只需要说:“观察者模式”。好的~万事大吉,从此世界清静了。

记录第一个模式:策略模式

利用一个实际应用场景来去解析这个模式,应该会更加容易理解:RPG游戏大家都玩过,如果我们设计一个简单RPG游戏,游戏中有角色,可以显示自己的名称,可以使用武器。好的~,我们根据上面描述再使用自己的OO思想很快设计了一个角色父类Character。并让各种职业继承此父类。

这是简单的UML图:

因为我们每个角色外观都是不一样的,,所以父类为抽象类,添加了抽象方法display()。子类女王和女巫负责实现自己的display()行为在屏幕上显示其外观。 这样设计完成了需求,并使代码能够重用,但是显然我们的老板当然不会让我们这么轻易拿到项目奖金,为了让该游戏更有特色亮点,主管们确定,此游戏需要添加“生育”的功能把其它RPG游戏比下去。这个时候,是我们OO程序员大展身手的时候了。 于是有了以下设计:

但是可怕的问题发生了:主管愤怒的找到你:我昨天在产品发布会议上看到了国王生孩子的功能。你这是在逗我么?你可能要去51job,智联招聘网站逛逛了! 这里我们犯了一个大家都会犯的错误:对代码的局部修改可能影响到全局。也许我们会想到Override。我可以把国王king类中的born()方法覆盖掉就像覆盖useWeapon一样(King使用的是单手剑,Queen使用的是魔法权杖)可是,如果以后加入狼人职业呢?(狼人生育小狼崽,但不会使用武器)。 我们认识到继承已经无法解决我们现在遇到的bug了,因为刚刚得到的最新通知,希望希望每六个月更新产品,增添一种角色,我们知道每当有新的角色出现,我们就要被迫检查并可能需要覆盖born()和useWeapon()·····这简直就是一种无穷无尽的酸爽~!!!

那我们使用接口吧:把useWeapon()从父类中取出来,放进一个useWeaponable接口中。这么一来,只有会使用武器的角色才实现此接口,同样的方式,也可以提取出一个bornable()接口,因为不是所有的角色都会生育,那么现在的设计如下:

经过如此修改,似乎修改了上面所有的bug。不过UseWeaponable和Bornable接口一开始似挺不错的,解决了问题,但是Java接口不具有实现代码,所以每次我们实现一种接口,总是要去实现接口中相关方法代码的编写,无疑是另外一种无穷无尽的酸爽~

既然无论如何我们无法完美解决这个问题,那么我们从新来考虑这个问题:

先提出一个设计原则:找出应用中可能需要变化之处,把他们独立起来,不要和那些不需要变化的代码混在一起。换句话说,如果每次新的需求一来,都会使某处代码发生变化,那么你就可以确定,这部分代码需要被抽出来,和其它稳定的代码有所区分。根据这个设计原则我们再去考虑这个问题,现在我们很明显的知晓:角色的useWeapon()行为和born()行为会随着角色的不同而不同。为了要把这两个行为从Character父类中分开,我们将他们从Character中取出来,建立一组新类来代表每个行为。

接着提出第二个设计原则:针对接口编程,而不是针对实现编程 我们利用接口代表每个行为,比方说UseWeaponBehavior 与BornBehavior,而行为的每个实现都将实现其中的一个接口。所以这次我们制造一组“行为”类,由行为类而不是角色子类去实现行为接口。

一 、在我们新设计中,角色的子类将使用接口(UseWeaponBehavior 与BornBehavior)所表示的行为。所以实际的实现不会被绑死在角色类中(松耦合),关于行为接口的设计如下:你曾经说,最大的愿望,

设计模式前言与策略模式(strategy)

相关文章:

你感兴趣的文章:

标签云: