策略模式-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();
}
}

本文例子的代码github地址: https://github.com/GoldArowana/design-patterns/tree/master/src/main/java/com/king/patterns/strategy

策略模式-Strategy(Java实现)的更多相关文章

  1. Java 设计模式系列(十二)策略模式(Strategy)

    Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...

  2. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  3. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  4. 十一个行为模式之策略模式(Strategy Pattern)

    定义: 定义一系列的算法,将每一个算法封装起来,并使它们之间可以相互替换,让算法具有可扩展性和对立性. 结构图: Context:环境类,算法的使用者.对外提供了算法使用的接口,并且持有一个抽象算法类 ...

  5. 策略模式(strategy pattern)

    策略模式在java集合中的TreeSet和TreeMap中得到了很好的应用,我们可以实现Comparator接口实现Compareto()方法来定义自己的排序规则,然后通过TreeSet,TreeMa ...

  6. 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...

  7. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  8. 设计模式 - 策略模式(Strategy Pattern) 具体解释

    策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...

  9. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

随机推荐

  1. 关闭windows系统的危险端口,命令行

    防火墙启用,增加禁用端口提供给外部访问 @echo off color E2 title 关闭常见的危险端口 echo 正在开启Windows防火墙 echo. netsh advfirewall s ...

  2. SQL SERVER 临时数据库 tempdb 迁移或增加文件

    临时数据库TempDB 虽然是临时库,但对整个数据库系统性能却起到很关键的作用:平时用到的中间数据集会暂时保存到TempDB 中,比如:临时表,排序,临时统计信息,一些中间结果数据,索引重建 等.我们 ...

  3. 从0开始的Python学习015输入与输出

    简介 在之前的编程中,我们的信息打印,数据的展示都是在控制台(命令行)直接输出的,信息都是一次性的没有办法复用和保存以便下次查看,今天我们将学习Python的输入输出,解决以上问题. 复习 得到输入用 ...

  4. 解决ajax跨域访问sessionid不一致问题

    根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务器就会以为 ...

  5. Golang学习:sublime text3配置golang环境

    最近导师让学习golang, 然后我就找了些有关golang的学习视频和网站. 昨天在电脑上下载了go tools, 之后在sublime上配置了golang的运行环境.By the way, 我的电 ...

  6. windows10远程桌面连接身份验证错误:函数不受支持,这可能是由于 CredSSP 加密 Oracle 修正

    前言:因windows10的更新,最近很多朋友会遇到mstsc远程连接桌面报错: windows10企业版解决方式: 按“win+R”,运行 gpedit.msc, 找:“计算机配置”->“管理 ...

  7. Linux(CentOS7)下远程拷贝文件,scp命令

    一.Linux版本 二.scp命令 scp [参数] [原路径] [目标路径] scp -P 22022 /home/file.war root@192.168.253.172:/home/test ...

  8. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  9. c# 上传图片到一个外链相册服务器

    这里一个免费上传图片的网站:https://imgbb.com 代码: private void post1(string filePath) { try { string fName = new F ...

  10. Winform开发中对界面的组织布局

    在设计界面的时候,不管是在Web端,还是在Winform端,或者是WPF或者移动界面等应用上,我们对界面的组织布局,一直是比较有趣的话题,而组织界面的好坏从用户的感受来看,可以提供程序可使用性高低,也 ...