基于Java的设计模式-策略模式

策略模式就是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

基本概念

策略模式主要是解决多种算法相似的情况下,使用if...else所带来的复杂和难以维护。当存在系统中有多个类,但是区分它们的是只是它们的直接行为,那我们可以把这些封装成一个一个类,然后进行任意替换。

策略模式存在三种角色:

  • Strategy 策略(算法)抽象
  • ConcreteStrategy 各种策略(算法)的具体实现
  • Context 策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。

案例

抽象类
复制代码
public interface Strategy {
	public void encrypt();
}

定义算法抽象类,方法为加密。

具体实现类

AES加密

复制代码
public class AESStrategy implements Strategy{

	@Override
	public void encrypt() {
		System.out.println("执行AES");
	}

}

MD5加密

复制代码
public class MD5Strategy implements Strategy {
	@Override
	public void encrypt() {
		System.out.println("执行MD5");
	}
}

继承算法抽象类,具体用AES、MD5方法进行实现。

外部环境封装类
复制代码
public class Context {
	private Strategy strategy;
	
	public Context(Strategy strategy) {
		this.strategy=strategy;
	}

	public void encrypt(){
		this.strategy.encrypt();
	}
}
测试类
复制代码
public class MainTest {

	public static void main(String[] args) {
		Context context = new Context(new AESStrategy());
		context.encrypt();
	}
}
小改一下

上面测试使用的时候,需要自己新建一个实例,阅读性不够好,所以就重新用枚举类修改一下。

算法枚举类

复制代码
public enum StrategyEnums {

	MD5("MD5算法"){
		@Override
		public Class<?> getStrategyClass() {
			return MD5Strategy.class;
		}
	},AES("AES算法"){
		@Override
		public Class<?> getStrategyClass() {
			return AESStrategy.class;
		}	
	};
	
	public abstract Class<?> getStrategyClass();
	
	private String className;
	
	StrategyEnums(){}
	
	StrategyEnums(String className){
		this.className= className;
	}
	
	public String getClassName(){
		return className;
	}
}

枚举方法返回算法具体实现类的Class,并加上类的算法描述。

复制代码
public class Context {
	private Strategy strategy;
	
	public Context(StrategyEnums enums) {
		try {
			this.strategy = (Strategy) enums.getStrategyClass().newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	public void encrypt(){
		this.strategy.encrypt();
	}
}

包装类的参数改为枚举值,根据枚举值来构建实例。

复制代码
public class MainTest {

	public static void main(String[] args) {
		Context context = new Context(StrategyEnums.AES);
		context.encrypt();
	}
}

测试可用,但是这样的话,就是需要同时维护枚举类,新构建一个算法具体类,同时要维护枚举类,不过就是增加了可读性。

总结

使用策略方式可以提供良好的扩展性、避免大量的if...else的条件判断,算法可以自由切换。当遇到多个类似的算法策略,可以考虑策略模式。

相关推荐
geovindu5 小时前
go: Mediator Pattern
设计模式·golang·中介者模式
wuminyu9 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
callJJ10 小时前
Spring Data Redis 两种编程模型详解:同步 vs 响应式
java·spring boot·redis·python·spring
kyriewen10 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
wbs_scy11 小时前
Linux线程同步与互斥(三):线程同步深度解析之POSIX 信号量与环形队列生产者消费者模型,从原理到源码彻底吃透
java·开发语言
jinanwuhuaguo12 小时前
(第三十三篇)五月的文明奠基:OpenClaw 2026.5.2版本的文明级解读
android·java·开发语言·人工智能·github·拓扑学·openclaw
xmjd msup13 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
9523613 小时前
SpringBoot统一功能处理
java·spring boot·后端
Lyyaoo.14 小时前
优惠券秒杀业务分析
java·开发语言
消失的旧时光-194314 小时前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法