你还不懂设计模式? - 策略设计模式

策略设计模式(Strategy Pattren)。当系统中有很多具有相同行为的类时。可以使用策略模式,使用一个类将它们封装起来统一调用,在不同的场景下调用不同的类来完成这个功能。

常用实现结构图如下:
在这里插入图片描述

策略设计模式在实际应用中还是非常广泛的。不如说系统登录(账号/密码,邮箱/密码,手机号/验证码,以及第三方登录),在线支付(支付宝,微信,银行卡等等),以及加密算法的配置。

首先还是来举个栗子,以支付流程为例:
①先创建支付策略接口:

public interface PayStrategy {
    /**
     * 在线支付接口
     * @param payerId 付款方ID
     * @param money 付款金额
     * @param payeeId 收款方ID
     */
    void pay(String payerId,BigDecimal money ,String payeeId);
}

② 创建支付宝支付策略和微信支付策略:

public class AlipayStrategyImpl implements PayStrategy {
    @Override
    public void pay(String payerId, BigDecimal money, String payeeId) {
        System.out.println(String.format("%s正在使用【支付宝】给%s付款%f元",payerId,payeeId,money.doubleValue()));
    }
}
public class WeChatPayStrategyImpl implements PayStrategy{
    @Override
    public void pay(String payerId, BigDecimal money, String payeeId) {
        System.out.println(String.format("%s正在使用【微信支付】给%s付款%f元",payerId,payeeId,money.doubleValue()));
    }
}

③ 创建策略使用客户端Client

public class Client {
    private static Map<PayType,PayStrategy>  payStrategys ;

    static {
        payStrategys = new ConcurrentHashMap<>(2);
        payStrategys.put(PayType.ALI_PAY,new AlipayStrategyImpl());
        payStrategys.put(PayType.WECHAT_PAY,new WeChatPayStrategyImpl());
    }

    public void payMoney(PayType payType, String payerId, BigDecimal money, String payeeId){
        PayStrategy payStrategy = Objects.requireNonNull(payStrategys.get(payType),"未找到合适的付款策略");
        payStrategy.pay(payerId,money,payeeId);

    }
    public static enum PayType{
        /**
         * 支付宝支付方式
         */
        ALI_PAY,
        /**
         * 微信支付方式
         */
        WECHAT_PAY,
    }
}

④ 测试

 public static void main(String[] args) {
        Client client = new Client();
        client.payMoney(PayType.ALI_PAY,"001",BigDecimal.valueOf(100),"002");
    }
 输出结果:
 001正在使用【支付宝】给002付款100.000000

再来看一下策略模式在源码中的应用。例如spring容器中bean的初始化策略。
在这里插入图片描述
bean的实例化策略在BeanFactroy#getBean的过程中会使用到。

AbstractAutowireCapableBeanFactory#instantiateBean()源码如下:

	/**
	 * Instantiate the given bean using its default constructor.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return a BeanWrapper for the new instance
	 */
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
			    //获取bean实例化策略,调用instantiate(mbd, beanName, parent)来实例化一个bean
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

可以看到策略模式的实现不仅仅可以使用implement。还可以配合使用extend 。所以说设计模式相当于武功招式。是死板的,但是在使用时可以根据实际应用场景进行适当变化,并配合其他的设计模式。不局限于一招一式。这才是一个武侠高手的必备素养。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值