【设计模式】策略模式

引例

【设计模式】策略模式_第1张图片
方案一
【设计模式】策略模式_第2张图片
说明:

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

方案二
将客户类和算法类分开
【设计模式】策略模式_第3张图片
说明:Sorting类可复用,但Sorting类仍不满足OCP
方案三
分离变化点:排序算法内部逻辑可能变化,排序算法个数可能变化,于是做成层次类,实现一个抽象的Sort接口
【设计模式】策略模式_第4张图片
说明:满足开闭原则、依赖倒置原则
Client类和算法实现类都依赖Sort抽象接口
具体使用而言,在 Client 中的 Sort 对象实例化某个具体的子类即可
还有一个问题:Client使用不同的Sort方法时可能需要进行重复的初始化、计算排序时间等与Sort层次类提供功能无关的工作
方案四
在Client和Sort层次类之间加上一个负责初始化/全局控制的类,用以协调Client和Sort层次类,即环境类Context
【设计模式】策略模式_第5张图片
代码实现

// Sort抽象接口
public interface Sort {
	int[] sort(int[] num);
}
// 具体排序类实现
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;
	}
}
// 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);
	}
}
// 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环境类之间增加一条反向依赖
【设计模式】策略模式_第6张图片

理论

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

通用结构

【设计模式】策略模式_第7张图片

使用场景

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

课后练习

练习一

【设计模式】策略模式_第8张图片
设计思路一:使用策略工厂的思路,DiscountStrategy作为抽象接口下接具体的discount策略做成一个打折策略层次类,DiscountStrategyFactory作为环境类,OrderService作为Client调用对应DiscountStrategyFactory再使用对应的打折策略
【设计模式】策略模式_第9张图片
DiscountStrategyFactory实现代码:

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);
	}
}

练习二

【设计模式】策略模式_第10张图片
【设计模式】策略模式_第11张图片

你可能感兴趣的:(#,设计模式,设计模式,策略模式,java,学习,笔记)