【设计模式】策略模式

引例


方案一

说明:

  1. 不满足OCP,添加新的排序算法或修改某个已有排序算法需要重新编译整个类
  2. 可复用性差,Sorting类不可被直接复用

方案二

将客户类和算法类分开

说明:Sorting类可复用,但Sorting类仍不满足OCP
方案三

分离变化点:排序算法内部逻辑可能变化,排序算法个数可能变化,于是做成层次类,实现一个抽象的Sort接口

说明:满足开闭原则、依赖倒置原则

Client类和算法实现类都依赖Sort抽象接口

具体使用而言,在 Client 中的 Sort 对象实例化某个具体的子类即可

还有一个问题:Client使用不同的Sort方法时可能需要进行重复的初始化、计算排序时间等与Sort层次类提供功能无关的工作
方案四

在Client和Sort层次类之间加上一个负责初始化/全局控制的类,用以协调Client和Sort层次类,即环境类Context

代码实现

java 复制代码
// Sort抽象接口
public interface Sort {
	int[] sort(int[] num);
}
java 复制代码
// 具体排序类实现
public class BubbleSort implements Sort{
@Override
	public int[] sort(int[] num) {
		int n = num.length;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - i - 1; j++) {
				if (num[j] > num[j + 1]) {
					int temp = num[j];
					num[j] = num[j + 1];
					num[j + 1] = temp;
				}
			}
		}
		return num;
	}
}
java 复制代码
// Context环境类的实现
public class Context {
	private Sort s;
	private long startTime;
	private long endTime;
	public Context(Sort s) {
		this.s = s;
	}
	public void startExc() {
		startTime = System.currentTimeMillis();
	}
	public void endExc() {
		endTime = System.currentTimeMillis();
	}
	public long getExcTime() {
		long exeTime = 0;
		exeTime = endTime - startTime;
		return exeTime;
	}
	public int[] sortIntArray(int[] a) {
		return s.sort(a);
	}
}
java 复制代码
// Client客户端代码实现
public class Client {
	public static void main(String[] args) {
		int[] arr = {64, 34, 25, 12, 22, 11, 90};
		Sort s = new BubbleSort();
		Context con = new Context(s);
		con.startExc();
		arr = con.sortIntArray(arr);
		con.endExc();
		System.out.println(Arrays.toString(arr));
		System.out.println(con.getExcTime());
	}
}

说明:这个设计模式仍有修改空间,应该通过在Sort具体类的sort方法中直接调用con.startExc()和con.endExc() 方法,这样得到的运行时间更加准确
方案五

在Sort层次类和Context环境类之间增加一条反向依赖

理论

定义

通过将一系列实现相同功能的算法封装起来,形成层次类,是得它们可以相互替换,且算法的变化不会影响使用算法的客户
说明

对象行为模式

通用结构

使用场景

  1. 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中
  2. 一个类中以条件语句并列起来的多种行为,每个条件分支可被封装到策略类中

课后练习

练习一

设计思路一:使用策略工厂的思路,DiscountStrategy作为抽象接口下接具体的discount策略做成一个打折策略层次类,DiscountStrategyFactory作为环境类,OrderService作为Client调用对应DiscountStrategyFactory再使用对应的打折策略

DiscountStrategyFactory实现代码:

java 复制代码
public class DiscountStrategyFactory {
	private static final Map<OrderType, DiscountStrategy> strategies =  new HashMap<OrderType, DiscountStrategy>();
	static {
	strategies.put(OrderType.NORMAL, new NormalDiscountStrateg());
	strategies.put(OrderType.GROUPON, new GrouponDiscountStrategy());
	strategies.put(OrderType.PROMOTION, new PromotionDiscountStrategy());
	}
	public static DiscountStrategy getDiscountStrategy(OrderType type) {
		return strategies.get(type);
	}
}

练习二


相关推荐
Asort1 分钟前
JavaScript设计模式(十四)——命令模式:解耦请求发送者与接收者
前端·javascript·设计模式
2025年一定要上岸5 分钟前
【日常学习】10-15 学习re
学习·算法·正则表达式
koo3646 分钟前
李宏毅机器学习笔记17
人工智能·笔记·机器学习
好家伙VCC9 分钟前
**发散创新:探索群体智能编程中的新境界**随着科技的飞速发展,群体智能逐渐成为编程领域的一大研究热点。本文将深入探讨群体智能的概念、优
java·python·科技
aramae20 分钟前
数据结构与算法(递归)
开发语言·经验分享·笔记·算法
秉承初心23 分钟前
Java 23种设计模式的详细解析
java·设计模式
程序员大雄学编程25 分钟前
「深度学习笔记1」深度学习全面解析:从基本概念到未来趋势
人工智能·笔记·深度学习
千码君201628 分钟前
Go语言:记录一下Go语言系统学习的第一天
java·开发语言·学习·golang·gin·并发编程·编译语言
聪明的笨猪猪29 分钟前
Java 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
学工科的皮皮志^_^40 分钟前
电压源和电流源学习理解
单片机·嵌入式硬件·学习