设计模式 策略(Strategy)模式
来源:互联网 发布:java并发编程艺术 编辑:程序博客网 时间:2024/06/14 18:09
一、定义
关于策略模式的定义,设计模式书中肯定都有,我就直接引用了:
策略模式定义了算法蔟,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 –摘自《Head First 设计模式》
听起来很抽象有没有,别急,如果你没有接触过这种模式,光看定义脑海中就能构建出框架,那可真是太牛了,反正我第一次看到这个定义是一脸的懵逼。不过没关系,当学习完了这个模式后,再重新来读这个定义,我相信你会有很多收获,而且思路能飘得很远。
二、需求
接下来让我们来根据实际的需求来探讨一下这个模式:临近元旦,公司准备元旦前一天下班后,直接从公司出发一起到某五星级大酒店聚餐吃饭,公司领导在微信群里直接发了定位,并让你规划几条合适的路线,方便给员工分组让其结伴而去。
你接到通知后,快马加鞭,过程很辛苦,但最终不负嘱托,规划出了几条路线:
/** * 这是交通路线的接口 */public interface IStrategyTrafficRoutes { //交通路线信息 void trafficRoutesInfo();}
为什么要使用接口,而不是直接使用具体的路线类?因为我们不应该把每个员工与具体的交通路线绑在一起,员工在出发前有权利改变路线(动态绑定),而当员工持有一个抽象交通路线类时,我们就可以在运行时动态的引用正确的具体交通路线类型(多态思想),所以我们应该针对接口编程,不针对实现编程。
第一种路线,步行最少,非常适合比较懒的员工
public class ShortestWalkRoutes implements IStrategyTrafficRoutes{ @Override public void trafficRoutesInfo() { //其实可以扩充出复杂的逻辑,但思路一样,所以就直接打印一句话得了 System.out.println("采用了步行距离最少的交通路线...分为1组"); }}
第二种路线换乘车辆最少,最适合不愿意多倒腾的员工了
public class TransferChangeLeastRoutes implements IStrategyTrafficRoutes { @Override public void trafficRoutesInfo() { System.out.println("采用了换成车辆最少的路线...分为2组"); }}
第三种路线花费时间最少,非常适合时间观念很强的人了
public class TimeLeastRoutes implements IStrategyTrafficRoutes { @Override public void trafficRoutesInfo() { System.out.println("采用了花费时间最少的路线...分为3组"); }}
第四种路线不拥挤,虽然时间长了点,但坐着比较舒心
public class MostComfortableRoutes implements IStrategyTrafficRoutes { @Override public void trafficRoutesInfo() { System.out.println("采用了最舒服的路线...分为4组"); }}
交通路线的不同,这也是这个需求(下班打卡-路上-吃饭)每个员工变化的部分,我们之所以把每种具体路线都单独的封装起来,而不是写成一个个方法添加到员工类内部,是因为考虑到代码的复用,符合封装变化的OO原则
规划完了,应该让员工自己选择路线了吧
/** * 这是一个员工类的基类 * @author zmj */public abstract class StaffBase { //员工的交通路线 IStrategyTrafficRoutes routes; public void setRoutes(IStrategyTrafficRoutes routes){ this.routes = routes; } //针对接口编程,而不是具体实现,这样我们就不会把特定路线和特定员工死死的绑定在一起 public void showStaffRoutes(){ routes.trafficRoutesInfo(); } //每个员工都有自己的名字(同样的还有员工号等等,我们只说思路) public abstract void showName();}
在StaffBase类中加入接口类型变量(而不是具体的交通路线),每个员工都会动态的设置这个变量以在运行时引用正确的行为类型(例如:步行最少、换成最少等),所以我们应该针对接口编程,而非针对实现编程。
这是员工1号
public class StaffOne extends StaffBase { public StaffOne(){ //员工1选择了步行最少的路线 //此处之所以没有直接new主要是不想让员工和路线绑的死死的 routes = RoutesFactory.getRoutes(1); } @Override public void showName() { System.out.print("本人张三:"); }}
这里采用静态工厂方法,让员工的代码与路线对象创建代码解耦
这是员工2号
public class StaffTwo extends StaffBase { public StaffTwo() { //员工2选择了换乘车辆最少 routes = RoutesFactory.getRoutes(2); } @Override public void showName() { System.out.print("本人李四:"); }}
这是员工3号
public class StaffThree extends StaffBase { public StaffThree(){ //员工3选择了花费时间最少的路线 routes = RoutesFactory.getRoutes(3); } @Override public void showName() { System.out.print("本人王五:"); }}
同样的可以还有员工4号5号…n号,这里就不写了,不过,如果你写的话,你会发现扩充起来是相当容易,只需要添加新类并继承StaffBase基类即可,不需要更改其他代码,符合对扩展开放,对修改关闭原则。
/** * 这是一个简单的静态工厂,主要是产生一些路线的对象 * @author zmj * */public class RoutesFactory { /** * @param id 员工的编号 * @return 返回其填写的交通路线 */ public static IStrategyTrafficRoutes getRoutes(int id) { IStrategyTrafficRoutes routes; switch (id) { case 1: //步行最少 routes = new ShortestWalkRoutes(); break; case 2: //换乘车辆最少 routes = new TransferChangeLeastRoutes(); break; case 3: //花费时间最少 routes = new TimeLeastRoutes(); break; case 4: //最舒服的路线 routes = new MostComfortableRoutes(); break; default: //如果新来一个员工,还没有员工编号呢,那就选择时间最少吧,毕竟新人嘛,迟到可不好 routes = new TimeLeastRoutes(); break; } return routes; }}
测试一下我们的这个设计吧
public class StrategyPatternTest { public static void main(String[] args) { //员工1号张三 StaffBase staff1 = new StaffOne(); //员工2号李四 StaffBase staff2 = new StaffTwo(); //员工3号王五 StaffBase staff3 = new StaffThree(); //员工1号选择了步行最少的交通方式 staff1.showName(); staff1.showStaffRoutes(); //员工2号选择了换乘车辆最少的交通方式 staff2.showName(); staff2.showStaffRoutes(); //员工3号选择了花费时间最少的交通方式 staff3.showName(); staff3.showStaffRoutes(); //由于今天时间充足,员工1号要求换成最舒服的路线 staff1.setRoutes(new MostComfortableRoutes()); staff1.showName(); staff1.showStaffRoutes(); }}
最终的运行结果
源码点击下载
- 设计模式----Strategy(策略)
- 设计模式--Strategy(策略)
- Strategy(策略)设计模式
- 设计模式----策略模式(Strategy)
- 设计模式--策略模式(Strategy)
- 设计模式C++(Strategy策略模式)
- 设计模式---策略模式(strategy)
- java 设计模式--策略模式(strategy)
- 【设计模式】之策略模式(Strategy)
- 设计模式之--策略模式(Strategy)
- 设计模式C++(Strategy策略模式)
- 设计模式(一)Strategy - 策略模式
- 设计模式之策略(strategy)模式
- 设计模式之策略模式(Strategy)
- 设计模式5--策略模式(Strategy)
- 设计模式-----策略模式(strategy)
- 浅学设计模式--策略(Strategy)模式
- PHP 设计模式 策略模式(Strategy)
- Logback配置
- WebSocket的意思(大白话)
- git reset soft,hard,mixed之区别深解
- 简单的连接数据库标准步骤
- 存储过程和触发器的取舍问题(优缺点分析)
- 设计模式 策略(Strategy)模式
- java.lang.ClassNotFoundException: Didn't find class "*****Activity" on path: /data/app/*******.apk
- A Demo Allocator——实现一个简单的自定义显式分配器
- 根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第3版)
- 171127之关于form表单提交ajaxForm和ajaxSubmit
- (MAC)java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider解决方法
- Hive注释乱码问题
- 关于mvc中@Html.DropDownListFor和@Html.DropDownList默认值无法选中问题简单总结
- 先码后看 模版技术概论 侵立删