《Head First 设计模式》[01] 策略模式
1、写在前面的话
2、策略模式

2.1 剥离变化之处
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
2.2 接口编程,独立实现
针对接口编程,而不是针对实现编程
针对接口编程,而不是针对实现编程

- 动作可以被其他对象复用,因为独立为动作,而跟鸭子类无关了,比如麻雀也可以使用fly()了
- 我们可以新增行为,且不影响既有行为类,也不影响使用飞行行为的鸭子类
2.3 整合
- 将剥离部分作为实例变量,加入到类中(即把FlyBehavior接口作为变量设置到Duck类中)
- 设置类似原来fly()的方法performFly(),调用已经作为实例变量的接口中定义的方法fly()
public class Duck {
protected FlyBehavior flyBehavior;
private String name;
private int size;
public String performFly() {
return flyBehavior.fly();
}
public String swim() {
return "Swimming ~ ~ ~";
}
}
public class Duck {
protected FlyBehavior flyBehavior;
private String name;
private int size;
public String performFly() {
return flyBehavior.fly();
}
public String swim() {
return "Swimming ~ ~ ~";
}
}
- 其他类实现行为接口
//通过翅膀飞行
public class FlyingByWings implements FlyBehavior {
public String fly() {
return "Flying By Wings~";
}
}
//通过翅膀飞行
public class FlyingByWings implements FlyBehavior {
public String fly() {
return "Flying By Wings~";
}
}
//通过火箭飞行
public class FlyingByRocket implements FlyBehavior {
public String fly() {
return "Flying By super-cool Rocket!!!";
}
}
//通过火箭飞行
public class FlyingByRocket implements FlyBehavior {
public String fly() {
return "Flying By super-cool Rocket!!!";
}
}
- 子类初始化时设定想要的实例变量
public class RocketDuck extends Duck {
public RocketDuck() {
flyBehavior = new FlyingByRocket();
}
}
public class RocketDuck extends Duck {
public RocketDuck() {
flyBehavior = new FlyingByRocket();
}
}
- 编辑测试类
public class Test {
public static void main(String[] args) {
RocketDuck rocketDuck = new RocketDuck();
System.out.println(rocketDuck.performFly());
}
}
public class Test {
public static void main(String[] args) {
RocketDuck rocketDuck = new RocketDuck();
System.out.println(rocketDuck.performFly());
}
}

public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}

3、模式总结
- 最开始,我们直接让子类继承父类来复用其方法,但是子类不同对于方法也不同,类的行为划分不清,同时方法覆盖的方式并不灵活;
- 然后,改变成通过实现接口来实现行为,行为划分清晰,可无法使用代码复用,后期维护困难;
- 最终,我们利用接口和多态原理,剥离行为,让一些专门的类来实现行为接口,让不同的子类去初始化不同的行为(实现类调用接口引用),完美解决了问题。
多用组合,少用继承
多用组合,少用继承
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

- 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种;
- 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 / 时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式;
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构;
- 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

4、本文涉及的设计原则汇总
- 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
- 针对接口编程,而不是针对实现编程
- 多用组合,少用继承
5、更多相关好文推荐
6、文章示例源码下载
《Head First 设计模式》[01] 策略模式的更多相关文章
- python设计模式之策略模式
每次看到项目中存在大量的if else代码时,都会心生一丝不安全感. 特别是产品给的需求需要添加或者更改一种if条件时,生怕会因为自己的疏忽而使代码天崩地裂,哈哈,本文的目的就是来解决这种不安全感的, ...
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- 设计模式入门,策略模式,c++代码实现
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
- 设计模式之策略模式和状态模式(strategy pattern & state pattern)
本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...
随机推荐
- django—xadmin中集成富文本编辑器ueditor
一.安装 pip命令安装,由于ueditor为百度开发的一款富文本编辑框,现已停止维护,如果解释器为python2,则直接pip install djangoueditor 解压包安装,python3 ...
- drupal7获取当前theme的路径
//方式一 $theme_path=drupal_get_path('theme', $theme); //方式二 $theme_path=path_to_theme();
- JavaScript语法详解:if语句&for循环&函数
本文首发于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. if语句 最基本的if语句 if语句的结构体:(格式) if (条件表达式) ...
- Python tuple
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表 语法 names = (a,b,c) 它只有2个方法,一个是count,一个是index. 当然也有可变元祖: 可 ...
- 使用 Azure PowerShell 管理 Azure 虚拟网络和 Windows 虚拟机
Azure 虚拟机使用 Azure 网络进行内部和外部网络通信. 本教程介绍了如何在虚拟网络中创建多个虚拟机 (VM),以及如何在虚拟机之间配置网络连接. 你将学习如何执行以下操作: 创建虚拟网络 创 ...
- wc 命令使用说明
wc 命令 使用说明 wc 命令还是很是简单的,通过 man 命令,可以见到可以选择的选项: wc option file 并且 wc 命令支持 管道操作 其中较为常用的命令选项 -c 字符的个数 - ...
- wing ide 6.0 注册
1.wing ide介绍 wing ide ,用过python的都知道是干嘛用的了吧,官网已经更新到6.0.0-1版本. 链接如下: Wing IDE Professional - Version 6 ...
- 第 15 章 位操作(invert4)
/*------------------------------------ invert4.c -- 使用位操作显示二进制 ------------------------------------* ...
- 【转】为什么Github没有记录你的Contributions
【转】为什么Github没有记录你的Contributions 字数985 阅读0 评论0 喜欢0 记录下为什么github 提交的时候,没有记录到 github 的那个日历上。 Paste_Imag ...
- 【Alpha 冲刺】 11/12
今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 完成app端api编写 未完成 文件上传api还没完成 孙浩楷 1. 与后端交接, 2. 完成图片在线编辑插件引入 未完成 陷入僵 ...