基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
设计模式是什么鬼(策略)
设计模式是什么鬼(策略)
阅读
1
2018-07-29
点击下方阅读原文,查看更多关于设计模式的文章
策略,
Strategy
,古时也称“计”,为了达成某个目标的方案,目标不同,方案也随之更改。例如特工执行任务时总要准备好几套方案以应对突如其来的变化,
A
计划实施过程中情况突变导致预案无法继续实施,则马上更换为
B
计划,正所谓计划不如变化快,提前策划固然非常重要,而随机应变更是不可或缺,只有保证这种可变的灵活性才能立于不败之地。世界永远都在变,唯一不变的就是变本身。
作为有思想的码农,我们当然也不能把程序写死了,一个设计优秀的系统,绝不是把现有类的代码改来改去,而一定是扩展类并接入系统,这样马上就能适应不同的用户需求。
就拿游戏机来举个例子,早期的俄罗斯方块风靡全球,后来国内流行一种掌机,只能玩俄罗斯方块这一个游戏,可过不了多久大家就玩腻了,于是热度降低这种游戏机很快就退出市场了,显然这是一种失败的设计模式。
后来任天堂出品的
Game
Boy
以及
Sony
的
PSP
则完全带来了不同的用户体验,系统提供了统一的卡槽接口,玩家只要更换卡带或
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
方法,接下来要做的只是组装上去便可以使用了。
计算器可以搞策略,那计算机呢?还记得我们在《设计模式是什么鬼(初探)》中举的计算机例子吧?很显然是同样是策略模式,大家可以自行写码试炼。
从以上的几个例子可以看出,我们的策略模式获得了极大的应用,策略实现类已经成为独立于宿主之外的模块,即插即用。可以组合成为一个整体,又可以分拆独立,可以发生关联,但绝不耦合,既对立又统一,这是唯物辩证法的绝佳体现。
推荐大而全的【后端技术精选】
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:你知道为什么要加 final 关键字了吗?
下一篇:
抛开硬实力,如何写简历才能帮你更快争取到面试机会?
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目