当前位置:首页>编程知识库>后端开发知识>设计模式是什么鬼(策略)
设计模式是什么鬼(策略)
阅读 1
2018-07-29
点击下方阅读原文,查看更多关于设计模式的文章
策略,Strategy,古时也称“计”,为了达成某个目标的方案,目标不同,方案也随之更改。例如特工执行任务时总要准备好几套方案以应对突如其来的变化,A计划实施过程中情况突变导致预案无法继续实施,则马上更换为B计划,正所谓计划不如变化快,提前策划固然非常重要,而随机应变更是不可或缺,只有保证这种可变的灵活性才能立于不败之地。世界永远都在变,唯一不变的就是变本身。
作为有思想的码农,我们当然也不能把程序写死了,一个设计优秀的系统,绝不是把现有类的代码改来改去,而一定是扩展类并接入系统,这样马上就能适应不同的用户需求。
就拿游戏机来举个例子,早期的俄罗斯方块风靡全球,后来国内流行一种掌机,只能玩俄罗斯方块这一个游戏,可过不了多久大家就玩腻了,于是热度降低这种游戏机很快就退出市场了,显然这是一种失败的设计模式。
后来任天堂出品的Game Boy以及SonyPSP则完全带来了不同的用户体验,系统提供了统一的卡槽接口,玩家只要更换卡带或MD就可以达到更换游戏的目的,做到了一机多用。
各种游戏卡带,更换游戏方便多了。
好了,开始实战部分,为了说明问题,我们继续发扬极简主义的优良传统,我们就做一个最简单的计算器好了,假设我们的计算器只能进行加减法,代码如下。
1public%20class%20Calculator%20%7B//%E8%BF%9D%E5%8F%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%8E%9F%E5%88%99%E7%9A%84%E5%81%9A%E6%B3%95%0A2%20%20%20%20public%20int%20add(int%20a,%20int%20b)%7B//%E5%8A%A0%E6%B3%95%0A3%20%20%20%20%20%20%20%20return%20a%20 %20b;%0A4%20%20%20%20%7D%0A5%0A6%20%20%20%20public%20int%20sub(int%20a,%20int%20b)%7B//%E5%87%8F%E6%B3%95%0A7%20%20%20%20%20%20%20%20return%20a%20-%20b;%0A8%20%20%20%20%7D%0A9%7D%0A
这样写ok吗?我们往后的扩展想想,如果随着我们的算法不断增加,如乘法、除法、次方、开方等等,那么这个计算器类就得不断的改啊改啊,每次升级算法我们都要把机器给拆开然后更改类代码,这岂不是作死?改到最后这个庞大的系统会不会变化这样?
或者是……如这般疯狂?
作死!的确是作死!我们来换个思路,先思考一下,既然不能把算法给写死在这里面,那一定要把这个算法给抽象一下,把实现细节从这个类里抽离出来,独立出来成为n个策略,就当下来讲我们一共有俩个策略,一个是加法策略,一个是减法策略,他们实现的都是同一个算法接口,接收参数为操作数a,以及被操作数b
public%20interface%20Strategy%20%7B//%E7%AE%97%E6%B3%95%E6%A0%87%E5%87%86%0A%20%20%20%20public%20int%20calculate(int%20a,%20int%20b);//%E6%93%8D%E4%BD%9C%E6%95%B0%EF%BC%8C%E8%A2%AB%E6%93%8D%E4%BD%9C%E6%95%B0%0A%7D
下来实现加法策略、减法策略。
public%20class%20Addition%20implements%20Strategy%7B//%E5%AE%9E%E7%8E%B0%E7%AE%97%E6%B3%95%E6%8E%A5%E5%8F%A3%0A%0A%20%20%20%20@Override%0A%20%20%20%20public%20int%20calculate(int%20a,%20int%20b)%20%7B//%E5%8A%A0%E6%95%B0%E4%B8%8E%E8%A2%AB%E5%8A%A0%E6%95%B0%0A%20%20%20%20%20%20%20%20return%20a%20 %20b;//%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%81%9A%E5%8A%A0%E6%B3%95%E8%BF%90%E7%AE%97%0A%20%20%20%20%7D%0A%0A%7D%0A
public%20class%20Subtraction%20implements%20Strategy%7B//%E5%AE%9E%E7%8E%B0%E7%AE%97%E6%B3%95%E6%8E%A5%E5%8F%A3%0A%0A%20%20%20%20@Override%0A%20%20%20%20public%20int%20calculate(int%20a,%20int%20b)%20%7B//%E5%87%8F%E6%95%B0%E4%B8%8E%E8%A2%AB%E5%87%8F%E6%95%B0%0A%20%20%20%20%20%20%20%20return%20a%20-%20b;//%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%81%9A%E5%87%8F%E6%B3%95%E8%BF%90%E7%AE%97%0A%20%20%20%20%7D%0A%0A%7D
算法写好了,开始写计算器。
%201public%20class%20Calculator%20%7B//%E8%AE%A1%E7%AE%97%E5%99%A8%E7%B1%BB%0A%202%20%20%20%20private%20Strategy%20strategy;//%E6%8B%A5%E6%9C%89%E6%9F%90%E7%A7%8D%E7%AE%97%E6%B3%95%E7%AD%96%E7%95%A5%0A%203%0A%204%20%20%20%20public%20void%20setStrategy(Strategy%20strategy)%20%7B//%E6%8E%A5%E5%85%A5%E7%AE%97%E6%B3%95%E7%AD%96%E7%95%A5%0A%205%20%20%20%20%20%20%20%20this.strategy%20=%20strategy;%0A%206%20%20%20%20%7D%0A%207%0A%208%20%20%20%20public%20int%20getResult(int%20a,%20int%20b)%7B%0A%209%20%20%20%20%20%20%20%20return%20this.strategy.calculate(a,%20b);//%E8%BF%94%E5%9B%9E%E5%85%B7%E4%BD%93%E7%AD%96%E7%95%A5%E7%9A%84%E7%BB%93%E6%9E%9C%0A10%20%20%20%20%7D%0A11%7D%0A
可以看到,计算器类里已经把之前的具体加减算法实现代码给剥离出去了,要用哪个算法,只需要注入进来,然后获得计算结果getResult实际上调用的是具体算法的calculate,我们来看怎样使用这个计算器。
%201public%20class%20Client%20%7B%0A%202%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%203%20%20%20%20%20%20%20%20Calculator%20calculator%20=%20new%20Calculator();//%E5%AE%9E%E4%BE%8B%E5%8C%96%E8%AE%A1%E7%AE%97%E5%99%A8%0A%204%20%20%20%20%20%20%20%20calculator.setStrategy(new%20Addition());//%E6%8E%A5%E5%85%A5%E5%8A%A0%E6%B3%95%E5%AE%9E%E7%8E%B0%0A%205%20%20%20%20%20%20%20%20int%20result%20=%20calculator.getResult(1,%201);//%E8%AE%A1%E7%AE%97%EF%BC%81%0A%206%20%20%20%20%20%20%20%20System.out.println(result);//%E5%BE%97%E5%88%B0%E7%9A%84%E6%98%AF%E5%8A%A0%E6%B3%95%E7%BB%93%E6%9E%9C2%0A%207%0A%208%20%20%20%20%20%20%20%20calculator.setStrategy(new%20Subtraction());//%E5%86%8D%E6%AC%A1%E6%8E%A5%E5%85%A5%E5%87%8F%E6%B3%95%E5%AE%9E%E7%8E%B0%0A%209%20%20%20%20%20%20%20%20result%20=%20calculator.getResult(1,%201);//%E8%AE%A1%E7%AE%97%EF%BC%81%0A10%20%20%20%20%20%20%20%20System.out.println(result);//%E5%BE%97%E5%88%B0%E7%9A%84%E6%98%AF%E5%87%8F%E6%B3%95%E7%BB%93%E6%9E%9C0%0A11%0A12%20%20%20%20%7D%0A13%7D%0A
注释已经写得非常明白了,相信大家都看懂了吧。那么我们这个计算器可以说是具有算法策略扩展性的,以后要有新的算法是不需要再更改任何现有代码的,只需要新写一个算法比如乘法Multiplication,并实现calculate方法,接下来要做的只是组装上去便可以使用了。
计算器可以搞策略,那计算机呢?还记得我们在《设计模式是什么鬼(初探)》中举的计算机例子吧?很显然是同样是策略模式,大家可以自行写码试炼。
从以上的几个例子可以看出,我们的策略模式获得了极大的应用,策略实现类已经成为独立于宿主之外的模块,即插即用。可以组合成为一个整体,又可以分拆独立,可以发生关联,但绝不耦合,既对立又统一,这是唯物辩证法的绝佳体现。
推荐大而全的【后端技术精选】
以上数据来源于网络,如有侵权,请联系删除。
评论 (0)