什么是策略模式?通俗的讲,策略模式就是把一组相似的行为(方法名相同)挨个封装在不同的类中,这些类都实现了同一个接口,也就是说这些类重写了这个方法,那么客户端在请求的时候需要什么行为就调用哪种行为。下面以一个例子说明一下。
假如接到一个需求,需要设计两种鸭子:红头鸭和绿头鸭;他们只是表现的不一样,都会游泳和gaga叫,学过面向对象的同学都知道我们可以设计一个父类,让这个父类Duck具有游泳和gaga叫的行为,再加上一个display的抽象行为让子类重写。这个时候而两种鸭子都继承Duck,这样便会减少代码量,也就减少了工作量。这种设计方式如下:

public abstract class Duck {public Duck(){}public void quack(){System.out.println("gaga~");}public void swim(){System.out.println("swim~");}public abstract void display();
}
public class GreenHeadDuck extends Duck {@Overridepublic void display() {System.out.println("Green Head");}
}
public class RedHeadDuck extends Duck {@Overridepublic void display() {System.out.println("Red Head");}
}
public class StrategyTest {public static void main(String[] args) {Duck greenHeadDuck = new GreenHeadDuck();Duck redHeadDuck = new RedHeadDuck();greenHeadDuck.display();greenHeadDuck.swim();greenHeadDuck.quack();System.out.println("-------------");redHeadDuck.display();redHeadDuck.swim();redHeadDuck.quack();}
}

其实这样写的确挺好的,但是如果有一天客户添加了额外的需求:添加会鸭子会飞的功能。这个时候如果为了方便,那就直接在Duck类里面添加flay行为:

public void fly(){System.out.println("fly");
}

貌似我们完成了工作,但是这里有一个小小的问题,并不是所有的鸭子都会飞啊,可是在父类里面添加了fly这个行为之后就说明所有的鸭子都可以飞,这显示是不科学的。也就是说继承存在缺陷:对类的局部改动,尤其是父类的局部改动,会影响其他部分,导致溢出效应
那要不在不能飞的子类里面重写掉父类的方法,这个时候是有用的,但是如果不能飞的鸭子和能飞的鸭子一样多,那我们的工作量不就又提了上来了吗。另外,直接这样草率地重写父类的方法,显然是违背了里氏原则,不清楚里氏原则的同学可以看我的另一篇博客。

假设在上面的基础上,客户又提出了新的需求:有些鸭子不会gaga叫。这个时候就会很烦,甚至会让程序员生出杀人灭口的想法(哈哈~)。可生活总得继续,项目还是得改,那该怎么改才能让后续客户提出的新问题不再这么烦人呢,这个时候策略模式就可以很好地帮我们解决这个问题,

策略模式:分别封装了行为接口,实现算法族,父类里面放行为接口对象,在子类里面具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。这种模式让行为的变化独立于算法的使用者。

首先,我们需要设定一些行为接口,不管是不是所有鸭子都需要,我们都应该把他们单独隔离出来。再让具体的类去实现这些接口。

public interface Swimable {void swim();
}
public class MySwimable implements Swimable {@Overridepublic void swim() {System.out.println("swim..");}
}public interface Flyable {void fly();
}
public class MyFlyable implements Flyable {@Overridepublic void fly() {System.out.println("fly...");}
}public interface Quackable {void quack();
}public class MyQuackable implements Quackable {@Overridepublic void quack() {System.out.println("quack...");}
}

接着,我们需要修改我们的鸭子父类,让各种行为成为父类的属性,通过行为的引用去调用具体的行为,重写无参构造器是为了避免所有的子类具有所有的行为。

public abstract class Duck {Flyable flyable;Quackable quackable;Swimable swimable;public Duck(){}public void quack(){quackable.quack();}public void swim(){swimable.swim();}public void fly(){flyable.fly();;}public abstract void display();
}

此时,轮到主角出场了,也就是客户需要的不同的鸭子,我们可以在构造器中添加上不同的行为,

public class RedHeadDuck extends Duck {public RedHeadDuck(){swimable = new MySwimable();quackable = new MyQuackable();}@Overridepublic void display() {System.out.println("Red Head");}
}public class GreenHeadDuck extends Duck {public GreenHeadDuck(){flyable = new MyFlyable();swimable = new MySwimable();}@Overridepublic void display() {System.out.println("Green Head");}
}

编写一个测试类让我们来看下效果

public class StrategyTest {public static void main(String[] args) {Duck greenHeadDuck = new GreenHeadDuck();Duck redHeadDuck = new RedHeadDuck();greenHeadDuck.display();greenHeadDuck.swim();greenHeadDuck.fly();System.out.println("-------------");redHeadDuck.display();redHeadDuck.swim();redHeadDuck.quack();}
}
Green Head
swim..
fly...
-------------
Red Head
swim..
quack...

后期如果还需要添加额外的行为,我们只需要添加行为接口以及实现类,在Duck类中添加上行为,在调用使用确定需要的行为即可。
此外,如果某一个行为有多个具体行为,比如,骑车有骑单车和骑摩托车之类的,也可以使用策略模式来实现。

public interface Rideable {void ride();
}
public class ByBike implements Rideable {@Overridepublic void ride() {System.out.println("ride bike");}
}
public class ByMotorcycle implements Rideable {@Overridepublic void ride() {System.out.println("ride bike");}
}

Duck中加上Rideable rideable;属性,在Duck的子类构造器中可以选择实例化一种行为方式:

rideable = new ByBike();
rideable = new ByMotorcycle();

策略模式的总结:

  1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。
  2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
  3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
  4. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
  5. 策略模式把算法的使用放到父类中,而算法的实现移到具体策略类中,实现了二者的分离。

设计模式——深入浅出策略模式相关推荐

  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经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

最新文章

  1. python 中文查找_使用python和regex查找字符串中的所有中文文本
  2. [YTU]_2445(C++习题 输入输出--公用继承)
  3. TF之DNN:利用DNN【784→500→10】对MNIST手写数字图片识别数据集(TF自带函数下载)预测(98%)+案例理解DNN过程
  4. 证监会:《证券期货业信息安全保障管理办法(征求意见稿) 》公开征求意见...
  5. 【英语学习】【Daily English】U11 Work L01 Would you like a tour of the office?
  6. python最佳框架_Web开发的10款最佳Python框架
  7. 06-在IDEA中实战Git
  8. mysql命令面板数据更改_宝塔面板数据库自动停止解决办法,宝塔面板MySQL数据库自动重启shell脚本...
  9. jdom 读取xml_JDOM分析器–将XML文件读取为Java对象
  10. 无线网卡802.11n、 Intel 5100 AGN
  11. python程序memory error_Python memory error的问题
  12. 多线程同步工具——volatile变量
  13. 腾讯AI开放平台使用尝试:通过文本翻译API进行汉译英
  14. python 英语词频统计_Python实现统计英文文章词频的方法分析
  15. mysql是正排还是倒排_正排索引与倒排索引的理解
  16. 360浏览器自动填充表单
  17. 安防厂商网络摄像机常用rtsp地址及端口
  18. 物联网是什么?物联网指的是哪些?
  19. 成佩涛-项目管理类经理必须了解的工具
  20. 通过电影票房预测来一览机器学习一般流程

热门文章

  1. 使用泰克示波器完成以太网调试
  2. 2014年北邮网研机试
  3. 总线隔离后如何接地?
  4. Python 之父 Guido 发推称加入微软搞开源
  5. 计算机仿真期末考试试题,计算机仿真试题
  6. 社会新“毒瘤”:AI骚扰电话
  7. JBuilder 2007 Enterprise Edition 王者归来
  8. 电脑上的串行和并行接口
  9. 用好压批量修改文件名
  10. 信创国产化的低代码平台,0元任君选购