设计模式入门—策略模式.ppt

上传人:文库蛋蛋多 文档编号:2308830 上传时间:2023-02-10 格式:PPT 页数:46 大小:3.20MB
返回 下载 相关 举报
设计模式入门—策略模式.ppt_第1页
第1页 / 共46页
设计模式入门—策略模式.ppt_第2页
第2页 / 共46页
设计模式入门—策略模式.ppt_第3页
第3页 / 共46页
设计模式入门—策略模式.ppt_第4页
第4页 / 共46页
设计模式入门—策略模式.ppt_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《设计模式入门—策略模式.ppt》由会员分享,可在线阅读,更多相关《设计模式入门—策略模式.ppt(46页珍藏版)》请在三一办公上搜索。

1、设计模式入门,Joe上班的公司做了一套相当成功的模拟鸭子游戏:SimUDuck游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫此系统的内部设计使用了标准的OO技术,设计了一个鸭子超类(Superclass),并让各种鸭子继承此超类,先从简单的模拟鸭子应用做起,现在我们得让鸭子能飞,主管们确定,此模拟程序需要会飞的鸭子来将竞争者抛在后头在这个时候,Joe的经理拍胸脯告诉主管们,Joe只需要一个星期就可以搞定。“毕竟,Joe是一个OO程序员这有什么困难?”,但是,可怕的问题发生了,Joe想到继承,利用继承来提供Duck的行为,会导致下列哪些缺点?代码在多个子类中重复运行时的行为不容易改变很难知道所有

2、鸭子的全部行为改变会牵一发动全身,造成其他鸭子不想要的改变,利用接口如何?,Joe认识到继承可能不是答案,因为他刚刚拿到来自主管的备忘录,希望以后每六个月更新产品(至于更新的方法,他们还没想到)Joe知道规格会常常改变,每当有新的鸭子子类出现,他就要被迫检查并可能需要覆盖fly()和quark()这简直是无穷无尽的噩梦所以,他需要一个更清晰的方法,让“某些”(而不是全部)鸭子类型可飞或可叫我可以把fly()从超类中取出来,放进一个“Flyable接口”中这么一来,只有会飞的鸭子才实现此接口同样的方式,也可以用来设计一个“Quackable接口”,因为不是所有的鸭子都会叫,你觉得这个设计如何?,

3、软件开发的一个不变真理,在软件开发上,有什么是你可以深信不疑的?不管你在何处工作,构建些什么,用何种编程语言,在软件开发上,一直伴随你的那个不变真理是什么?软件开发的一个不变真理CHANGE不管当初软件设计得多好,一段时间之后,总是需要成长与改变,否则软件就会“死亡”,把问题归零,现在我们知道使用继承并不能很好地解决问题,因为鸭子的行为在子类里不断地改变,并且让所有的子类都有这些行为是不恰当的Flyable与Quackable接口一开始似乎还挺不错,解决了问题(只有会飞的鸭子才继承Flyable),但是Java接口不具有实现代码,所以继承接口无法达到代码的复用这意味着:无论何时你需要修改某个行

4、为,你必须得往下追踪并在每一个定义此行为的类中修改它,一不小心,可能会造成新的错误幸运的是,有一个设计原则,恰好适用于此状况,设计原则,找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起如果每次新的需求一来,都会使某方面的代码发生变化,那么你就可以确定,这部分的代码需要被抽出来,和其他稳定的代码有所区分下面是这个原则的另一种思考方式:“把会变化的部分取出并封装起来,以便以后可以轻易地改动或扩充此部分,而不影响不需要变化的其他部分”。这样的概念很简单,几乎是每个设计模式背后的精神所在所有的模式都提供了一套方法让“系统中的某部分改变不会影响其他部分”。该是把鸭子的行为从

5、Duck类中取出的时候了!,分开变化和不会变化的部分,设计鸭子的行为,如何设计那组实现飞行和呱呱叫的行为的类呢?我们希望一切能有弹性,毕竟,正是因为一开始鸭子行为没有弹性,才让我们走上现在这条路我们还想能够“指定”行为到鸭子的实例比方说,我们想要产生一个新的绿头鸭实例,并指定特定“类型”的飞行行为给它干脆顺便让鸭子的行为可以动态地改变好了换句话说,我们应该在鸭子类中包含设定行为的方法,这样就可以在“运行时”动态地“改变”绿头鸭的飞行行为,设计原则,针对接口编程,而不是针对实现编程我们利用接口代表每个行为,比方说,FlyBehavior与QuackBehavior,而行为的每个实现都将实现其中的

6、一个接口所以这次鸭子类不会负责实现Flying与Quacking接口,反而是由我们制造一组其他类专门实现FlyBehavior与QuackBehavior,这就称为“行为”类由行为类而不是Duck类来实现行为接口这样的做法迥异于以往,以前的做法是:行为来自Duck超类的具体实现,或是继承某个接口并由子类自行实现而来这两种做法都是依赖于“实现”,我们被实现绑得死死的,没办法更改行为(除非写更多代码)在我们的新设计中,鸭子的子类将使用接口(FlyBehavior与QuackBehavior)所表示的行为,所以实际的“实现”不会被绑死在鸭子的子类中(换句话说,特定的具体行为编写在实现了FlyBeha

7、vior与QuakcBehavior的类中),从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现这样,鸭子类就不再需要知道行为的实现细节,实现鸭子的行为,整合鸭子的行为,关键在于,鸭子现在会将飞行和呱呱叫的动作“委托”(delegate)别人处理,而不是使用定义在Duck类(或子类)内的呱呱叫和飞行方法,疑问?,初始化实例变量的做法不够弹性但是想一想,因为quackBehavior的实例变量是一个接口类型,我们能够在运行时,通过多态的魔力动态地给它地指定不同的QuickBehavior实现类花一点儿时间想一想,你如何实现一个其行为可以在运行时改变的鸭子,测试Duck的代码,

8、下一步:改进?,动态设定行为,假设我们想在鸭子子类中通过“设定方法(setter method)”来设定鸭子的行为,而不是在鸭子的构造器内实例化,“有一个”可能比“是一个”更好,当你将两个类结合足来使用,如同本例一般,这就是组合(composition)这种做法和“继承”不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象“组合来的设计原则多用组合,少用继承使用组合建立系统具有很大的弹性,不仅可将算法封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可,策略模式(Strategy Pattern),策略模式定义算法族,分别封装起来,让它们之间可以互相替换

9、,此模式让算法的变化独立于使用算法的客户,在下面,你将看到一堆杂乱的类与接口,这取至一个动作冒险游戏你将看到代表游戏角色的类和角色可以使用的武器行为的类每个角色一次只能使用一种武器,但是可以在游戏的过程中换武器,应用,排序,在什么情况下应当使用策略模式,如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为一个系统需要动态地在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多态性原则,客户端可以选择使用任何一个具体算法类,并只持

10、有一个数据类型是抽象算法类的对象一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复杂的和只与算法有关的数据如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念,策略模式的优点,策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式

11、,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后,策略模式的缺点,客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量,Any Question?,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号