✅你在工作中是如何使用设计模式的?

典型回答

工作中常用的设计模式有很多,如单例、工厂、策略、模板等。一般在工作中,是可以把策略、工厂和模板一起结合着来使用的。

当我们需要有多个具体的策略服务的时候,那不同的内容放到策略服务中,那些公共的东西就可以抽象出来放到模板方法中了。那这些策略服务该如何管理呢?什么时候用什么策略服务呢?这时候就可以借助工厂来管理这些服务。

如以下例子, 我们需要定义一个支付服务,里面有一个支付方法:

public interface PayService {
    public void pay(PayRequest payRequest);


}

class PayRequest {

}

这是一个单独的接口,只定义了一个方法,那么,我们再把所有支付渠道中公共的代码抽出来,定义一个抽象类:

public abstract class AbstractPayService implements PayService {

    @Override
    public void pay(PayRequest payRequest) {
        //前置检查
        validateRequest(payRequest);
        //支付核心逻辑
        doPay(payRequest);
        //后置处理
        postPay(payRequest);
    }

    public abstract void doPay(PayRequest payRequest);

    private void postPay(PayRequest payRequest) {
        //支付成功的后置处理
    }

    public void validateRequest(PayRequest payRequest) {
        //参数检查
    }
}

这个抽象类中首先把pay方法给实现了,然后编排了几个其他的方法,这些公共的方法在抽象类中直接实现了,具体的支付核心实现,留给实现类去实现就行了。

然后我们就可以定义多个策略服务了:

@Service
public class AlipayPayService extends AbstractPayService {
    @Override
    public void doPay(PayRequest payRequest) {
        //支付宝支付逻辑
    }
}

@Service
public class WechatPayService extends AbstractPayService {
    @Override
    public void doPay(PayRequest payRequest) {
        //微信支付逻辑
    }
}

这些服务定义好了之后,需要有一个地方统一管理,那就定义一个工厂吧:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class PayServiceFactory {

    @Autowired
    public Map<String, PayService> payServiceMap = new ConcurrentHashMap<>();

    public PayService getPayService(String payChannel) {
        // alipay -> alipayPayService
        // wechat -> wechatPayService
        return payServiceMap.get(payChannel + "PayService");
    }

}

在工厂中,把PayService的所有实现全部都注入到payServiceMap中,然后再需要用的是,直接调他的getPayService方法就行了。

✅Spring的@Autowired能用在Map上吗?

这样,在使用的时候,只需要通过工厂就能获取对应的策略服务进行服务调用了:

public class PayDomainService {
    @Autowired
    PayServiceFactory payServiceFactory;

    public void pay(PayRequest payRequest) {
        String payChannel = payRequest.getPayChannel();
        payServiceFactory.getPayService(payChannel).pay(payRequest);
    }
}

以上,我们借助了Spring,结合了策略、模板以及工厂,实现了我们想要的功能,通过多种设计模式,减少重复代码,提升可维护性,也让代码更容易阅读和理解。

原文: https://www.yuque.com/hollis666/xkm7k3/kzq0dwtbtgps9oe1