Java设计模式—策略模式,简单易懂

设计模式【策略模式】

今天不搞别的就来点素的,分享一个Java日常开发中常用的设计模式——策略模式
在企业开发中,策略模式运用也非常广泛,用的好可以大大的提高代码的管理性,对相关算法或行为族管理一目了然。。 同时也具有更好的维护性和拓展性。



一. 简单认识

某些类具有相同的行为或相似的算法实现,把它们更加抽象化的管理。能在运行时动态的选择相应的行为活动进行更改。他的重心不是在算法怎么实现而是管理,如何组织、调用这些算法,从而让程序结构更加灵活。这就是策略模式,属于设计模式中的行为型模式。

优缺点

优点
  1. 减少了冗余的代码判断 if…else… ,根据当前场景相互替换不同的算法实现,完全独立更易于维护,符合开闭原则
  2. 提供了管理相关算法族的办法,恰当的把公共的代码放在接口中大大减少了代码的重复。
缺点
  1. 项目中存在多个策略类时,存在很多不同的算法实现,提高了系统的复杂性
  2. 所有的策略都需要暴露

二. 撸代码

1. 首先我们需要定义抽象出来相同行为的接口

要有获取标识的方法,用于区分各种算法的实现表示唯一标识

public interface Payment {
	
	/**
	 * 支付行为
	 */
	Result pay();
	
	/**
	 * 获取支付方式
	 */
	List<String> getMode()
}

管理基类行为算法标识枚举

public enum PayModeEnum {
	Wx,
	Alipay
	;
}

2. 定义策略工厂

这里要声明是Spring的组件,不然项目启动时无法执行生命周期,为成员属性赋值。
第一种: 借用构造方法让框架自动注入

@Component
public class PaymentStrategy {
	
	// 策略类工厂容器
	private static final Map<String, Payment> CONTEXT = new HashMap<>();

	// 通过构造方法把策略实现注册到容器中
	public PaymentStrategy(List<Payment> paymentList) {
		paymentList.forEach(payment -> {
			payment.getMode().forEach(mode -> {
				CONTEXT.putIfAbsent(mode, payment);
			});
		});
	}
	
	public Result pay(PayModeEnum payModeEnum) {
		Payment payment = Objects.requireNonNull(CONTEXT.get(payModeEnum.toString()));
		return payment.pay();
	}
}

第二种: 手动初始化从容器进行注入

@Component
public class PaymentStrategy implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;

	private static final Map<String, Payment> CONTEXT = new HashMap<>();
	
    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

	@Override
    public void afterPropertiesSet() {
    	// 手动将所有实现注册到工厂容器
        applicationContext.getBeansOfType(Payment.class)
                .values()
                .forEach(payment -> payment.getMode().forEach(mode -> CONTEXT.putIfAbsent(mode, payment)));
    }

	public Result pay(PayModeEnum payModeEnum) {
		Payment payment = Objects.requireNonNull(CONTEXT.get(payModeEnum.toString()));
		return payment.pay();
	}
}

3. 基类实现行为算法

@Service
public class WxPaymentServiceImpl implements WxPaymentService, Payment {
	
	// 指定基类的标识信息
	@Override
	public List<String> payMode() {
		return Collections.singletonList(PayModeEnum.Wx.toString());
	}

	@Override
	public Result pay() {
		// 微信支付算法逻辑实现
		//todo: ...
	}
}
@Service
public class AlipayPaymentServiceImpl implements AliPayPaymentService, Payment {
	
	// 指定基类的标识信息
	@Override
	public List<String> payMode() {
		return Collections.singletonList(PayModeEnum.Alipay.toString());
	}

	@Override
	public Result pay() {
		// 阿里支付算法逻辑实现
		//todo: ...
	}
}

4. 使用

使用时直接获取对应策略,调用相应门面方法传递标识,完成行为算法的动态改变。

@RestController
@RequestMapping(value = "/payment")
public class PaymentController {

	@Autowried
	private PaymentStrategy paymentStrategy;

	@GetMapping
	public Result pay() {
		return paymentStrategy.pay(PayModeEnum.Wx.toString());
	}
}

总结

到此,一个简单、易于维护的策略模式就完成了。对于新加的支付基类只需要实现接口,指定标识和完成算法实现就ok了,对拓展开放,对之前已经完整的算法没有进行修改、关闭了修改,符合设计原则。。

关注我 ~ 分享更多技术干货

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值