通用策略模式实现 — Flea Strategy

1. 概述

策略模式(Strategy Pattern)作为一种软件设计模式,用来实现对象的某个行为,该行为在不同的场景中拥有不同的实现逻辑。它定义了一组算法,同时将这些算法封装起来,并使它们之间可以互换。

常用的策略模式有如下三个角色:

  • 抽象策略角色 — Strategy
    抽象策略类,通常为一个接口,其中定义了某个策略行为【即策略算法标识】。

  • 具体策略角色 — ConcreteStrategy
    具体策略类,实现抽象策略中的策略行为;每一个具体策略类即代表一种策略算法。

  • 上下文角色 — Context
    上下文类,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

本篇在上述常用的策略模式基础上,结合门面模式和调整后的策略上下文,构建了一套通用策略模式实现。

下面我们这套通用策略模式来模拟一下各种动物的喊叫行为:

2. 参考

flea-frame-common使用之通用策略模式实现 源代码

3. 实现

3.1 定义Flea策略接口类 — IFleaStrategy

该类定义了通用的策略行为,T 类型表示 Flea 策略执行结果对应的类型,P 类型表示 Flea 策略上下文参数。 具体代码如下:

/*** Flea策略接口,定义统一的策略执行方法。** @param <T> Flea策略执行结果对应的类型* @param <P> Flea策略上下文参数* @author huazie* @version 1.1.0* @since 1.1.0*/
public interface IFleaStrategy<T, P> {/*** 策略执行** @param contextParam Flea策略上下文参数* @return 策略执行结果对应的类型* @throws FleaStrategyException Flea策略异常* @since 1.1.0*/T execute(final P contextParam) throws FleaStrategyException;
}

3.2 定义狗叫喊声策略类 — DogVoiceStrategy

/*** 狗喊叫声策略** @author huazie* @version 1.1.0* @since 1.1.0*/
public class DogVoiceStrategy implements IFleaStrategy<String, String> {@Overridepublic String execute(String name) throws FleaStrategyException {return "阿狗【" + name + "】正在叫喊着;汪汪汪";}}

3.3 定义猫叫喊声策略类 — CatVoiceStrategy

/*** 猫喊叫声策略** @author huazie* @version 1.1.0* @since 1.1.0*/
public class CatVoiceStrategy implements IFleaStrategy<String, String> {@Overridepublic String execute(String name) throws FleaStrategyException {return "阿猫【" + name + "】正在叫喊着;喵喵喵";}}

3.4 定义鸭叫喊声策略类 — DuckVoiceStrategy

/*** 鸭喊叫声策略** @author huazie* @version 1.1.0* @since 1.1.0*/
public class DuckVoiceStrategy implements IFleaStrategy<String, String> {@Overridepublic String execute(String name) throws FleaStrategyException {return "阿鸭【" + name + "】正在叫喊着;嘎嘎嘎";}}

3.5 定义策略上下文接口类 — IFleaStrategyContext

策略上下文接口,定义统一的策略上下文调用方法,同时可通过 getContext 获取上下文参数,setContext 设置上下文参数。

/*** Flea策略上下文接口,定义统一的策略上下文调用方法。** @param <T> Flea策略执行结果对应的类型* @param <P> Flea策略上下文参数* @author huazie* @version 1.1.0* @since 1.1.0*/
public interface IFleaStrategyContext<T, P> {/*** 策略上下文调用** @param strategy 策略名称* @return 策略执行结果对应的类型* @throws FleaStrategyException Flea策略异常* @since 1.1.0*/T invoke(String strategy) throws FleaStrategyException;/*** 设置策略上下文参数** @param contextParam 上下文参数对象* @since 1.1.0*/void setContext(P contextParam);/*** 获取策略上下文参数** @return 策略上下文参数* @since 1.1.0*/P getContext();
}

3.6 定义Flea抽象策略上下文类 — FleaStrategyContext

Flea 抽象策略上下文类,封装了策略执行的逻辑,对外屏蔽高层模块对策略的直接访问。抽象方法 init 用于初始化 Flea 策略实现 Map,该方法由Flea 策略抽象上下文的子类实现,并在策略上下文子类实例化时,调用该方法完成具体初始化的工作。

/*** Flea抽象策略上下文,封装了公共的策略执行逻辑,* 其中Flea策略Map由其子类进行初始化,键为策略名,* 值为具体的Flea策略实例。** @param <T> Flea策略执行结果对应的类型* @param <P> Flea策略上下文参数* @author huazie* @version 1.1.0* @since 1.1.0*/
public abstract class FleaStrategyContext<T, P> implements IFleaStrategyContext<T, P> {private Map<String, IFleaStrategy<T, P>> fleaStrategyMap; // Flea策略Mapprivate P contextParam; // Flea策略上下文参数/*** 初始化策略上下文** @since 1.1.0*/public FleaStrategyContext() {fleaStrategyMap = init();}/*** 初始化策略上下文** @param contextParam Flea策略上下文参数* @since 1.1.0*/public FleaStrategyContext(P contextParam) {this();this.contextParam = contextParam;}/*** 初始化Flea策略Map** @return Flea策略Map* @since 1.1.0*/protected abstract Map<String, IFleaStrategy<T, P>> init();@Overridepublic T invoke(String strategy) throws FleaStrategyException {if (ObjectUtils.isEmpty(fleaStrategyMap)) {throw new FleaStrategyException("The Strategy Map is not initialized!");}IFleaStrategy<T, P> fleaStrategy = fleaStrategyMap.get(strategy);if (ObjectUtils.isEmpty(fleaStrategy)) {throw new FleaStrategyNotFoundException("The Strategy [name =\"" + strategy + "\"] is not found!");}return fleaStrategy.execute(contextParam);}@Overridepublic void setContext(P contextParam) {this.contextParam = contextParam;}@Overridepublic P getContext() {return contextParam;}
}

3.7 定义动物叫喊声策略上下文类 — AnimalVoiceContext

动物叫喊声策略上下文,继承 Flea 抽象策略上下文,实现 init 方法,用于初始化 Flea 策略实现 Map,其中 key 为 策略名,value 为 具体的动物叫喊声策略实现类;Collections.unmodifiableMap 用于返回一个 只读Map

/*** 动物叫喊声策略上下文** @author huazie* @version 1.1.0* @since 1.1.0*/
public class AnimalVoiceContext extends FleaStrategyContext<String, String> {private static Map<String, IFleaStrategy<String, String>> fleaStrategyMap;static {fleaStrategyMap = new HashMap<>();fleaStrategyMap.put("dog", new DogVoiceStrategy());fleaStrategyMap.put("cat", new CatVoiceStrategy());fleaStrategyMap.put("duck", new DuckVoiceStrategy());fleaStrategyMap = Collections.unmodifiableMap(fleaStrategyMap);}public AnimalVoiceContext() {}public AnimalVoiceContext(String contextParam) {super(contextParam);}@Overrideprotected Map<String, IFleaStrategy<String, String>> init() {return fleaStrategyMap;}
}

3.8 定义Flea策略门面 — FleaStrategyFacade

/*** Flea策略门面,定义策略调用的统一入口。** @author huazie* @version 1.1.0* @since 1.1.0*/
public class FleaStrategyFacade {private FleaStrategyFacade() {}/*** 策略门面调用方法** @param strategy            策略名* @param fleaStrategyContext 策略上下文* @param <T>                 Flea策略执行结果对应的类型* @param <P>                 Flea策略上下文参数* @return Flea策略执行结果对应的类型* @throws FleaStrategyException Flea策略异常* @since 1.1.0*/public static <T, P> T invoke(String strategy, IFleaStrategyContext<T, P> fleaStrategyContext) throws FleaStrategyException {return fleaStrategyContext.invoke(strategy);}
}

4. 测试

单元自测类可查看 FleaStrategyTest。

/*** @author huazie* @version 1.1.0* @since 1.1.0*/
public class FleaStrategyTest {private static final FleaLogger LOGGER = FleaLoggerProxy.getProxyInstance(FleaStrategyTest.class);@Testpublic void testStrategy() {AnimalVoiceContext context = new AnimalVoiceContext("旺财");LOGGER.debug(FleaStrategyFacade.invoke("dog", context));context.setContext("Tom");LOGGER.debug(FleaStrategyFacade.invoke("cat", context));AnimalVoiceContext context1 = new AnimalVoiceContext();context1.setContext("Donald");LOGGER.debug(FleaStrategyFacade.invoke("duck", context1));}
}

单元测试类运行结果如下:

flea-common使用之通用策略模式实现相关推荐

  1. 采用注解实现策略模式

    目录 一.前言 二.采用简单的注解方式进行业务策略模式 (一)场景举例 (二)实现方案 1.基本代码准备 2.基本功能接口定义 3.定义注解与不同的策略实现 4.业务实际使用 5.测试及结果展示 三. ...

  2. 【设计模式】 模式PK:策略模式VS状态模式

    1.概述 行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下. 策略模式(左)和状态模式(右)的通用类图. 两个类图非常相似,都是通过Cont ...

  3. java 策略模式会员_七:策略模式(不同等级会员打折算法)

    定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化: 下面给出策略模式的类图,引自百度百科. 策略模式在LZ第一次接触到的时 ...

  4. c++switch实现猜拳_策略模式+简单工厂+注解消除 if-else/switch-case

    消除代码中的 if-else/switch-case 在很多时候,我们代码中会有很多分支,而且分支下面的代码又有一些复杂的逻辑,相信很多人都喜欢用 if-else/switch-case 去实现.做的 ...

  5. 策略模式(封装一系列的功能,使之可以相互替换)

    策略模式和工厂方法模式很类似(感觉策略模式是工厂方法模式的一部分) 策略模式就是将一系列的功能封装起来(用工厂方法模式封装),使之可以相互替换(C++多态调用),从而使功能更加独立,与客户程序的耦合性 ...

  6. 策略模式原来这么简单!

    前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 无论是面试还是个人的提升,设计模式是必学的.今天来讲解策略模式~ ...

  7. 从业务出发,来谈谈策略模式,清爽的飞起~

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 路易小七 来源 | cnblogs.com/l ...

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

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

  9. Java设计模式之十一 ---- 策略模式和模板方法模式

    前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...

  10. 设计模式实战-策略模式(Strategy Pattern)

    0 联系我 图片标题 1.Q群[Java开发技术交流]:jq.qq.com/?_wv=1027&a- 2.完整博客链接:www.shishusheng.com 3.知乎:www.zhihu.c ...

最新文章

  1. ACM 竞赛高校联盟 练习赛 第二场 BC
  2. 【iOS】日历行程的增删改查(完整)
  3. EasyStack华丽亮相OpenStack Days China
  4. css 单行文本溢出显示省略号
  5. Cannot load 32-bit SWT libraries on 64-bit JVM
  6. YGC前后新生代变大?
  7. 【JQuery】将Json Object序列化成URL的QueryString
  8. 07LaTeX学习系列之---Latex源文件的结构
  9. django19:项目开发流程
  10. 【LeetCode笔记】11.盛最多水的容器(Java、双指针法)
  11. 数据结构-链表3-循环链表
  12. Python浅谈gevent实现协程
  13. 在WPF里面显示DIB图片格式的图片
  14. Flex 与外部的数据通信(HTTPService,URLLoader和URLRequest)
  15. linux上的pcb设计软件,PCB设计软件(CadSoft Eagle Professional)
  16. android 腾讯视频 dlan,腾讯视频dlna怎么用 dlna功能使用方法 (图文)
  17. 计算机毕业设计之java+ssm基于web的考研助手网站
  18. 【TsinsenA1339】JZPLCM(顾昱洲) 树状数组
  19. Process Hacker 简单介绍
  20. android获取整体存储空间大小,Android 获取剩余存储空间

热门文章

  1. 联想服务器怎么装系统和配置,联想服务器的配置及操作系统的安装.pdf
  2. 基于PHP和MySQL的奶茶网站,基于PHP和MySQL的网站设计与实现
  3. 分布式光伏系列:分布式光伏电站 运行与维护方案一览(zz)
  4. 基于U3D的VR开发教程:(1)基础环境配置
  5. 2B市场行业,面向2025年技术趋势与5大机会,赶快来看一看吧
  6. Torus登场:CoreOS打造的新一代分布式存储系统
  7. java 实现工作日计算
  8. mt4和mt5的区别
  9. Python爬虫(1)
  10. R语言实现分层抽样(Stratified Sampling)以iris数据集为例