4
回答
程序设计咨询--支持多支付渠道的支付门面类设计
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

场景为支付门面类,封装了多个支付渠道,比如channelA,channelB,channelC.

伪代码如下:

public class PaymentFacadeService {
	@Autowired
	private APaymentService aPaymentService;
	@Autowired
	private BPaymentService bPaymentService;
	@Autowired
	private CPaymentService cPaymentService;

	public PayResultDTO pay(PayOrderDTO dto) {
		String payChannel = dto.getPayChannel();
		if (payChannel.equalsIgnoreCase("channelA"))
			return aPaymentService.pay(dto);
		else if (payChannel.equalsIgnoreCase("channelB"))
			return bPaymentService.pay(dto);
		else if (payChannel.equalsIgnoreCase("chnanelC"))
			return cPaymentService.pay(dto);
		return null;
	}
}

总觉得将所有的渠道Service作为成员变量罗列在门面类中不够优雅。不知可有更优雅的实现方案?

举报
zgw06629
发帖于3年前 4回/107阅
共有4个答案 最后回答: 3年前

最终的解决方案:

spring配置:

<bean id="paymentFacadeService"
	class="com.XXX.PaymentFacadeService">
	<property name="channelServiceMap">
	    <map>
		<entry key="channelA">
		    <bean class="com.XXX.ChannelAPaymentService"></bean>
		</entry>
		<entry key="channelB">
		    <bean class="com.XXX.ChannelBPaymentService"></bean>
		</entry>
		<entry key="channelC">
		    <bean class="com.XXX.ChannelCPaymentService"></bean>
		</entry>
	    </map>
	</property>
</bean>



支付门面类:

public class PaymentFacadeService {
    private Map<String,AbstractPaymentService> channelServiceMap;
     
    public PayResultDTO pay(PayOrderDTO dto) {
        String payChannel = dto.getPayChannel();
         
        return channelServiceMap.get(payChannel).pay(dto);
    }
    public void setChannelServiceMap(Map<String,   AbstractPaymentService> serviceMap) {
        this.channelServiceMap = serviceMap;
    }
     
}



引用来自“zgw06629”的评论

最终的解决方案:

spring配置:

<bean id="paymentFacadeService"
	class="com.XXX.PaymentFacadeService">
	<property name="channelServiceMap">
	    <map>
		<entry key="channelA">
		    <bean class="com.XXX.ChannelAPaymentService"></bean>
		</entry>
		<entry key="channelB">
		    <bean class="com.XXX.ChannelBPaymentService"></bean>
		</entry>
		<entry key="channelC">
		    <bean class="com.XXX.ChannelCPaymentService"></bean>
		</entry>
	    </map>
	</property>
</bean>



支付门面类:

public class PaymentFacadeService {
    private Map<String,AbstractPaymentService> channelServiceMap;
     
    public PayResultDTO pay(PayOrderDTO dto) {
        String payChannel = dto.getPayChannel();
         
        return channelServiceMap.get(payChannel).pay(dto);
    }
    public void setChannelServiceMap(Map<String,   AbstractPaymentService> serviceMap) {
        this.channelServiceMap = serviceMap;
    }
     
}



你这个场景本身就不是外观模式的适用场景,应该是策略模式,那样更优雅。

你目前适用外观,会让后续维护者迷惑。

--- 共有 1 条评论 ---
zgw06629谢谢您的意见!但能给个简单的demo吗?好让我直观的感受一下策略模式。目前的实现方式我已经觉得很优雅了。 3年前 回复
顶部