策略模式-Strategy(Java实现)
策略模式-Strategy
在策略模式中,一个类(策略使用者)可以更改自己的执行策略. 比如以排序算法为例子, 多种排序算法都归属于排序算法, 但是实现的算法细节不同, 使用者可以很轻松地替换策略, 选择其中一个来执行任务.
本文基本就是copy了一下Ilkka Seppälä(github里的iluwatar)的例子, 他的例子非常形象.
场景是这样的: 有一个屠龙勇士, 他会替换不同的装备(策略)来对抗不同的龙.
类关系图如下:

依赖关系图如下:

定义
DragonSlayingStrategy接口
策略模式有很多的策略, 在这里把屠龙策略抽象出来, 定义一下屠龙场景中的策略DragonSlayingStrategy接口.
/**
* 屠龙策略接口
*/
@FunctionalInterface
public interface DragonSlayingStrategy {
void execute();
}
DragonSlayer类
在这里定义了屠龙勇士DragonSlayer.
屠龙勇士有一个默认策略, 还可以进行替换策略的操作, 还可以使用当前的策略来进行攻击.
/**
* 屠龙勇士
*/
public class DragonSlayer {
/**
* 屠龙策略
*/
private DragonSlayingStrategy strategy; /**
* 如果是空参构造器, 那么赋上一个默认的策略
*/
public DragonSlayer() {
strategy = new DragonSlayingStrategy() {
@Override
public void execute() {
System.out.println("默认策略: 拳打脚踢");
}
};
} /**
* 传入一个策略, 根据这个策略来进行实例化屠龙勇士
*/
public DragonSlayer(DragonSlayingStrategy strategy) {
this.strategy = strategy;
} /**
* 策略是可以随时变的, change一下就好了
*/
public DragonSlayer changeStrategy(DragonSlayingStrategy strategy) {
this.strategy = strategy;
return this;
} /**
* 使用当前策略来执行屠龙
*/
public void goToBattle() {
this.strategy.execute();
}
}
实现
基本的模型已经出来, 但是咱们还没有创建具体的策略类呢, 让我们来创建两个吧
SpellStrategy类
/**
* 念魔咒策略
*/
public class SpellStrategy implements DragonSlayingStrategy{ @Override
public void execute() {
System.out.println("魔咒策略: 念魔咒把龙封印掉");
}
}
FireStrategy类
/**
* 火器策略
*/
public class FireStrategy implements DragonSlayingStrategy {
@Override
public void execute() {
System.out.println("火器策略: 用火烧");
}
}
Main
这里是运行示例
public class Main {
public static void main(String[] args) {
// 有一个屠龙勇士
DragonSlayer slayer = new DragonSlayer();
System.out.println("\n幼龙出现啦");
slayer.goToBattle();
/*-************世界安静了片刻**************-*/
System.out.println("\n冰龙出现啦!");
//屠龙勇士发现可以用火克制他, 于是换了火器策略, 进行攻击
slayer.changeStrategy(new FireStrategy()).goToBattle();
/*-************世界安静了片刻**************-*/
System.out.println("\n远古巨龙出现啦!");
// 巨龙太强大了, 只能装备好念魔咒这个技能, 然后攻击
slayer.changeStrategy(new SpellStrategy()).goToBattle();
/*-************世界安静了片刻**************-*/
System.out.println("\n魔龙出现啦");
// 屠龙勇士用光了所有策略, 现场学会了一个新的技能, 还没来得及给这个技能起名字呢, 屠龙要紧, 快快快
slayer.changeStrategy(new DragonSlayingStrategy() {
@Override
public void execute() {
System.out.println("神秘技能: 顿悟出一套从天而降的掌法, 如来神掌!");
}
}).goToBattle();
/*-************世界安静了片刻**************-*/
System.out.println("\n神龙出现啦");
// 屠龙勇士利用函数式编程发明了一种新的神级招式: 洗脑
slayer.changeStrategy(()-> System.out.println("洗脑策略: 洗脑~~~~~~")).goToBattle();
}
}

策略模式-Strategy(Java实现)的更多相关文章
- Java 设计模式系列(十二)策略模式(Strategy)
Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...
- JAVA设计模式之策略模式 - Strategy
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...
- 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)
在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...
- 十一个行为模式之策略模式(Strategy Pattern)
定义: 定义一系列的算法,将每一个算法封装起来,并使它们之间可以相互替换,让算法具有可扩展性和对立性. 结构图: Context:环境类,算法的使用者.对外提供了算法使用的接口,并且持有一个抽象算法类 ...
- 策略模式(strategy pattern)
策略模式在java集合中的TreeSet和TreeMap中得到了很好的应用,我们可以实现Comparator接口实现Compareto()方法来定义自己的排序规则,然后通过TreeSet,TreeMa ...
- 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- 设计模式 - 策略模式(Strategy Pattern) 具体解释
策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...
- HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)
策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...
随机推荐
- MySQL, XE7使用FireDAC连接MySQL数据库
发现使用DBExpress进行MySQL连接老是有莫名其妙的问题,直接改为FireDAC 在上一篇的DataSnap服务框架程序中,将连接的数据库由MSSQL改为本文的MySQL 使用的MySQL数据 ...
- 城市经纬度 json
[ { "name": "北京市", "log": "116.46", "lat": "3 ...
- SQL Server含逗号分隔的数据匹配维表
日常有时候导出数据需求时,数据列会遇到带有分隔符的ID,但又需要匹配维表(如下图所示)将ID变成名称. 这种情况可以采用“分隔-匹配-合并”的方法 具体代码为: -- 准备工作1:创建事实表数据 CR ...
- Go语言打造以太坊智能合约测试框架(level2)
传送门: 柏链项目学院 第二课 智能合约自动化编译 前期内容回顾 之前我们的介绍的是如何通过solc编译智能合约,并且调用智能合约,本节我们继续实践,将智能合约的代码自动化编译以及abi文件生成搞定. ...
- eclipse 开发web 项目,使用gradle 需要安装的插件
1.Buildship Gradle 扩展 eclipse IDE 以支持使用 Gradle 构建软件.此解决方案由 Eclipse 基金会提供 2.EGradle Editor (主要用来编写gra ...
- kvm热添加和热迁移
a.热添加磁盘 1.创建磁盘 qemu-img create -f qcow2 web01-add01.qcow2 5G 2.附加磁盘设备 virsh attach-disk web01 /opt/w ...
- 数据的偏度和峰度——df.skew()、df.kurt()
我们一般会拿偏度和峰度来看数据的分布形态,而且一般会跟正态分布做比较,我们把正态分布的偏度和峰度都看做零.如果我们在实操中,算到偏度峰度不为0,即表明变量存在左偏右偏,或者是高顶平顶这么一说. 一.偏 ...
- ES6 Promise 用法讲解
Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...
- zookeeper-3.5.4-beta安装
官网地址 https://zookeeper.apache.org/ 下载文件解压进入conf目录下将zoo_sample.cfg名称修改为zoo.cfg # The number of millis ...
- NLP语义匹配
参考资料 [搜狗语义匹配技术前沿]https://www.jiqizhixin.com/articles/2018-10-25-16?from=synced&keyword=%E6%90%9C ...