前言:最近在看Head First设计模式,有所收获记录总结一下,今天说一下策略模式解决的问题。

<1> 策略模式是根据外部不同的需求选择不同的策略来解决不同需求的问题。
<2>策略模式更适用于算法,加减,计算公式,和应对与一种产品后期可能会出现多变的需求情况下使用。
<3>策略模式将可变的需求分组成不同的对象或者接口,来进行策略组的不同实现。
<4>通过策略分组,使得每个分组有不同的策略应对这个分组行为产生的不同需求。
下面我来设计一个策略需求。

1 需求:

以鸭子为例,有小黄鸭,黑鸭子,橡皮鸭子,木头鸭子等...

2 功能:

小黄鸭:会飞,会叫,会游泳,会烧烤...
黑鸭子:会飞,会叫,会游泳,会烧烤...
橡皮鸭子:会叫,会游泳...
木头鸭子:会游泳...

策略模式设计(使用StartUML的ER随手画的不规范凑合看):

可以看到,我们针对不同的鸭子,我们对鸭子赋予的功能策略是不同的,当然如果你说木头鸭子可以烧烤,请出门右转,自己找烧烤店。。。

3 实例讲解:废话不多说举一个小黄鸭的例子,上代码

步骤一:定义鸭子抽象超类,策略分组的接口,公共的方法
 1 package com.alibaba.strategy;
 2
 3 /**
 4  * 鸭子类 -- 策略模式超类
 5  *
 6  * @author Mr.Tk
 7  * @date 2019/3/09 16:25
 8  */
 9 public abstract class Duck {
10
11     /**
12      * 飞行行为
13      */
14     FlyBehavior flyBehavior;
15
16     /**
17      * 叫声行为
18      */
19     QuackBehavior quackBehavior;
20
21     public Duck() {
22
23     }
24
25     /**
26      * 鸭子的颜色
27      */
28     public abstract void display();
29
30     /**
31      * 委托执行飞行方法
32      */
33     public void performFly() {
34         flyBehavior.fly();
35     }
36
37     /**
38      * 委托执行叫声方法
39      */
40     public void performQuack() {
41         quackBehavior.quack();
42     }
43
44     /**
45      * 游泳方法
46      */
47     public void swim() {
48         System.out.println("鸭子在游泳,请勿打扰。烧烤请左转...");
49     }
50
51 }

步骤二:创建鸭子的行为接口,策略分组

package com.alibaba.strategy;/*** 鸭子的飞行,行为接口** @author Mr.Tk* @date 2019/3/09 16:28*/
public interface FlyBehavior {void fly();
}

package com.alibaba.strategy;
/*** 鸭子叫声,行为接口** @author Mr.Tk* @date 2019/3/09 16:29*/
public interface QuackBehavior {void quack();
}

步骤三:策略组实现的策略,应对每个策略分组下面有不同的策略去应对不同的需求
 1 package com.alibaba.strategy.impl;
 2
 3 import com.alibaba.strategy.FlyBehavior;
 4
 5 /**
 6  * 展翅高飞
 7  *
 8  * @author Mr.Tk
 9  * @date 2019/3/09 16:29
10  */
11 public class FlyWithwings implements FlyBehavior {
12     @Override
13     public void fly() {
14         System.out.println("展翅高飞的鸭子。。。");
15     }
16 }  

package com.alibaba.strategy.impl;import com.alibaba.strategy.FlyBehavior;/*** 不会飞行的鸭子** @author Mr.Tk* @date 2019/3/09 16:29*/
public class FlyNoWay implements FlyBehavior {@Overridepublic void fly() {System.out.println("本鸭不会飞,告辞。。。");}
}

 1 package com.alibaba.strategy.impl;
 2
 3 import com.alibaba.strategy.QuackBehavior;
 4 /**
 5  * 鸭子叫
 6  *
 7  * @author Mr.Tk
 8  * @date 2019/3/09 16:46
 9  */
10 public class Quack implements QuackBehavior {
11     @Override
12     public void quack() {
13         System.out.println("鸭子叫声。。。");
14     }
15 }

 1 package com.alibaba.strategy.impl;
 2
 3 import com.alibaba.strategy.QuackBehavior;
 4 /**
 5  * 不会叫的鸭子
 6  *
 7  * @author Mr.Tk
 8  * @date 2019/3/09 16:46
 9  */
10 public class MuteQuack implements QuackBehavior {
11     @Override
12     public void quack() {
13         System.out.println("鸭子不会叫。。。");
14     }
15 }

 1 package com.alibaba.strategy.impl;
 2
 3 import com.alibaba.strategy.QuackBehavior;
 4
 5 /**
 6  * 吱吱叫的鸭子
 7  *
 8  * @author Mr.Tk
 9  * @date 2019/3/09 16:46
10  */
11 public class Squeak implements QuackBehavior {
12     @Override
13     public void quack() {
14         System.out.println("吱吱叫的鸭子。。。");
15     }
16 }

步骤四:我们来实现一个鸭子的独有策略
 1 package com.alibaba.strategy;
 2
 3 import com.alibaba.strategy.impl.FlyWithwings;
 4 import com.alibaba.strategy.impl.Quack;
 5
 6 /**
 7  * 小黄鸭
 8  *
 9  * @author Mr.Tk
10  * @date 2019/3/09 16:51
11  */
12 public class YellowDuck extends Duck {
13
14     public YellowDuck() {
15         quackBehavior = new Quack();
16         flyBehavior = new FlyWithwings();
17     }
18
19     @Override
20     public void display() {
21         System.out.println("烧烤小黄鸭。。。");
22     }
23 }

步骤五:Test测试一下鸭子是否实现小黄鸭的功能了
 1 package com.alibaba.strategy;
 2
 3 public class Test {
 4
 5     public static void main(String[] args) {
 6         //创建小黄鸭
 7         Duck yellowDuck = new YellowDuck();
 8         //飞起来
 9         yellowDuck.performFly();
10         //叫起来
11         yellowDuck.performQuack();
12         //游泳
13         yellowDuck.swim();
14         //展示
15         yellowDuck.display();
16     }
17 }

console运行结果:
展翅高飞的鸭子。。。
鸭子叫声。。。
鸭子在游泳,请勿打扰。烧烤请左转...
烧烤小黄鸭。。。Process finished with exit code 0

4 说一下优缺点

4.1  策略接口可以相互结合使用,可以随意切换。
4.2 符合程序设计的“开闭原则”,如果该策略组下需要不同的策略,我们新增一个策略即可,不必改动原有代码。
4.3 使用策略模式可以减少我们代码中因为业务增加,而产生大量的 if...else..从而使服务层以为业务的增加而变得臃肿起来。

5 缺点

5.1 我们需要了解所有的策略类,来决定到底使用哪一个策略组下的那个策略。
5.2 随着业务的增加,可能每个策略组下的策略会越来越多。
解决方案:我的下一篇博客,会介绍享元模式,此篇博客就不说策略模式以外的东西了,有兴趣的可以自行百度,皮一下 -.-。
6 项目应用场景的例子
一个地区的仲裁(法院)机构,会有不同的案件诉讼费用的计算方法。比如假设上海仲裁他的计算方式是,费用 = 受理费*当事人是否本地户籍(是20% / 不是 30%);而北京仲裁委就是另一种计算方式。还有其他的省下面有大大小小很多市,每个市的机构计算费用方法不一样,我们使用策略模式进行省的分组,每个省下的每个市有不同的计费策略。这里举的一个例子只是我在项目中遇到的业务场景,当然策略模式使用在算法上面的业务比较多,针对不同的业务去使用设计模式来帮助我们更好的完成工作是每个"攻城狮"的基本功,希望大家可以get不同的思路,有所收获。

转载于:https://www.cnblogs.com/yuxiaoming/p/10501598.html

Head First设计模式一:策略模式相关推荐

  1. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  2. 换个姿势学设计模式:策略模式

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:公众号「闻人的技术博客」 前言 前段时间,接到一个 ...

  3. 研磨设计模式之 策略模式--转

    http://www.uml.org.cn/sjms/201009092.asp 研磨设计模式之 策略模式   2010-09-09 作者:云飞龙行 来源:云飞龙行的blog   先感谢众多朋友的支持 ...

  4. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

  5. C++设计模式之策略模式(Strategy)

    Strategy策略模式 作用:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. UML图: 代码实现 #include <iostream& ...

  6. python策略模式包含角色_详解Python设计模式之策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中"不见了,或者简 ...

  7. 一篇博客读懂设计模式之-----策略模式

    设计模式之策略模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的对象 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下 ...

  8. 面向对象设计模式之策略模式

    面向对象设计模式之策略模式 1.策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 2.抽象鸭子类,鸭子飞行行为在此处类似于算法族 1 package ...

  9. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

  10. 策略设计模式_设计模式之策略模式总结

    再上一篇文章<设计模式之策略模式>中,我们通过模拟鸭子项目,了解了什么是策略模式,怎么使用策略模式.本文将通过鸭子项目的学习,对策略模式进行总结. 策略模式: 分别封装行为接口,实现算法族 ...

最新文章

  1. 超细粒度分析XLNet中神奇的Attention Mask
  2. 每日程序C语言25-查找100以内的素数
  3. Union与Union All的区别
  4. Eclipse+MyEclipse+Tomcat下配置建立Web Project
  5. SpringBoot源码篇:Spring5内置tomcat实现code-based的web.xml实现
  6. php游戏充值平台源码,PHP平台源码下载-PHP第四方支付平台源码pc端下载
  7. Hyper-V固定虚拟机IP
  8. mysql中两点之间距离的计算
  9. Ucenter实现多个网站同步登录
  10. 人工智能如何自我进化
  11. rc时间常数定义_rc电路时间常数的定义及计算
  12. Vue3-歌词根据时间自动滚动
  13. 数据库与身份认证(学习笔记)
  14. xp系统显示错误1053服务器,使用故障恢复控制台解决XP系统无法启动的常见故障...
  15. 扫码反馈,“码”上回复:二维码在业主意见反馈中的应用
  16. 千年鸿蒙盼尔来兮,古言爱情誓言
  17. 【网址】在线手册/手册网
  18. 英飞凌硅麦可以接收到超声波吗?
  19. 全栈修炼:如何从Web前端迈向全栈开发
  20. Service id not legal hostname (service_cmn)

热门文章

  1. php怎样连接上数据库服务器,php怎样连接数据库
  2. yum 安装boost
  3. web前端技术基础课程讲解之浅谈对soket的理解
  4. matplotlib之scatter
  5. 安装opencv3.4.0报错
  6. Ansible 入门:安装 简例 playbook应用
  7. typescript设置默认值_TypeScript输入参数的默认值一例,以及对应生成的JavaScript代码分析...
  8. 系统管理员最应该读的5本书_系统管理员的8本书
  9. vco为什么低频下起振困难_为什么协作如此困难?
  10. node Express 框架