设计模式之策略模式(多种实现方式)

介绍

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
主要是为了代码的解耦,避免每次新增策略的时候都影响到之前的策略逻辑(开闭原则),降低代码的耦合有利于后面代码的延伸(新增行为),并确保每次新增策略(功能)时都不会影响到原来的代码逻辑!

策略模式UML图 :
在这里插入图片描述

一、策略模式代码实现

策略接口
public interface BonusStrategy {
	public void bonus();
}
策略实现
public class T1Handler implements BonusStrategy {

	@Override
	public void bonus() {
		System.out.println("T1级别年终奖");
	}

}
public class T2Handler implements BonusStrategy {

	@Override
	public void bonus() {
		System.out.println("T2级别年终奖");
	}

}
策略背景
public class BonusMapContext {

	private static final Map<String, BonusStrategy> STRATEGY_MAP = new HashMap<String, BonusStrategy>();

	static {
		STRATEGY_MAP.put("T1", new T1Handler());
		STRATEGY_MAP.put("T2", new T2Handler());
	}

	public static void getBonus(String staffLevel) {
		BonusStrategy bonusStrategy = STRATEGY_MAP.get(staffLevel);
		if (null == bonusStrategy) {
			System.out.println("非正常级别!!! 无奖金");
			return;
		}
		bonusStrategy.bonus();
	}
}

这样,一个简单的策略模式就编写出来了,目前我们只有T1和T2级别的员工才有年终奖,其他级别的员工都是没有奖金的! 剥削的资本主义!!! 如果我们公司规模变大了(世界500强),需要新增一个T3级别年终奖,我们只需新增一个T3Handler类就行了,然后手动把它put到STRATEGY_MAP里去就行, 但是这样我们还是违背了’开闭原则’,为了更好的维护,此时我们将代码稍微修改一下.

实现InitializingBean接口(自动注册)

新增bonusRegister方法

public class BonusMapContext {

	private static final Map<String, BonusStrategy> STRATEGY_MAP = new HashMap<String, BonusStrategy>();

	public static void bonusDispatch(String staffLevel) {
		BonusStrategy bonusStrategy = STRATEGY_MAP.get(staffLevel);
		if (null == bonusStrategy) {
			System.out.println("非正常级别!!! 无奖金");
			return;
		}
		bonusStrategy.bonus();
	}

	public static void bonusRegister(String staffLevel, BonusStrategy bonusStrategy) {
		if (STRATEGY_MAP.containsKey(staffLevel)) {
			System.out.println("当前类型已存在!!!");
			return;
		}
		STRATEGY_MAP.put(staffLevel, bonusStrategy);
	}
}

策略类实现InitializingBean接口,并自动注册

@Component
public class T1Handler implements BonusStrategy, InitializingBean {

	@Override
	public void bonus() {
		System.out.println("T1级别奖金");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		BonusMapContext.bonusRegister("T1", this);
	}

}
@Component
public class T2Handler implements BonusStrategy, InitializingBean {

	@Override
	public void bonus() {
		System.out.println("T2级别的奖金");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		BonusMapContext.bonusRegister("T2", this);
	}

}

我们在BonusMapContext中新增了注册方法,这样子我们以后新增策略的时候,只需要让该策略实现InitializingBean接口,并自动注册即可,这样子就遵循了’开闭原则’,不需要每次都要去修改STRATEGY_MAP,但是这样子我们后面的每个策略类都要实现InitializingBean接口,这部分的逻辑是与业务完全无关的,虽然实现了自动注册,但是代码还是有冗余,需要注意的是,该实现类必须要有@Component、@Service注解,否则afterPropertiesSet方法将不起作用! 因为只有bean被初始化时,才会执行afterPropertiesSet方法!!!

基于SpringBoot实现策略模式
@Component("T1")
public class T2Handler implements BonusStrategy {

	@Override
	public void bonus() {
		System.out.println("T2级别的奖金");
	}

}
@Component("T2")
public class T1Handler implements BonusStrategy {

	@Override
	public void bonus() {
		System.out.println("T1级别奖金");
	}

}

此时代码已经编写完毕,我们新建个testController来测试一下

@Controller
public class testController {

	@Autowired
	private BonusMapContext context;

	@ResponseBody
	@RequestMapping("/test")
	public void insertProduct() throws Exception {
		for (int i = 0; i < 3; i++) {
			context.bonusDispatch("T" + i);
		}
	}
}
   打印结果为

在这里插入图片描述

需要注意的是Handler类中的value必须要是T1或者T2等自己定义的类型,否则将默认使用类名(驼峰命名)作为key,这样子我们还是会找不到对应的策略类.
经过上面代码的比较,我们会发现基于SpringBoot实现策略模式是最友好的一种方式,我们后续新增策略只需要新增Handler类,然后添加注解就可以了,SpringBoot会帮我们自动注入到上下文中的STRATEGY_MAP中,实际上在日常工作中,这样那样的需求可以用到策略模式,但是在使用设计模式的时候,我们需要同时考虑到后期的维护,如果是简单的逻辑并且后续拓展类型的可能性很小,我们可以直接使用if else,这样的代码是最简洁最实用的,如果项目中同事的水平看不懂,这也会带来问题,如果为了使用设计模式而使用,那么这将毫无价值

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
策略模式是一种行为设计模式,它允许在运行时选择算法的行为,这些算法在一个特定的上下文中执行。在这种情况下,我们需要在支付系统中实现多种支付方式,可以使用策略模式来解决这个问题。 下面是一个简单的实现: 首先,我们需要定义一个支付策略接口,它包含一个支付方法: ```java public interface PaymentStrategy { void pay(double amount); } ``` 接下来,我们可以实现具体的支付策略,例如支付宝、微信支付和信用卡支付: ```java public class AliPayStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用支付宝支付:" + amount + "元"); } } public class WeChatPayStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用微信支付:" + amount + "元"); } } public class CreditCardPayStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用信用卡支付:" + amount + "元"); } } ``` 现在我们可以创建一个支付上下文对象,它包含一个当前使用的支付策略: ```java public class PaymentContext { private PaymentStrategy paymentStrategy; public PaymentContext(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } public void pay(double amount) { paymentStrategy.pay(amount); } } ``` 使用时,我们可以创建一个支付上下文对象,然后设置需要的支付策略: ```java PaymentContext paymentContext = new PaymentContext(new AliPayStrategy()); paymentContext.pay(100.0); ``` 输出结果为: ``` 使用支付宝支付:100.0元 ``` 同样,我们也可以使用其他的支付策略来支付: ```java paymentContext = new PaymentContext(new WeChatPayStrategy()); paymentContext.pay(200.0); paymentContext = new PaymentContext(new CreditCardPayStrategy()); paymentContext.pay(300.0); ``` 输出结果分别为: ``` 使用微信支付:200.0元 使用信用卡支付:300.0元 ``` 这样,我们就可以灵活地选择不同的支付方式来支付。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值