用工厂模式设计支付业务场景,包含跨境支付,支付宝、微信、银联支付,并画出类图
1: 理清题目要求并扩展题目, 题目要求是用工程模式设计支付业务场景
假设第一个场景是: 已经存在统一支付接口,支付宝接口,微信支付接口,银联支付接口,于是画下设计图(不是类图),
写出代码如下:(第一个是简单工厂模式)
public interface IPayment {
/**
* 支付金额
* @param money
*/
void pay(Double money);
}
public class AliPayment implements IPayment {
@Override
public void pay(Double money) {
System.out.println("使用支付宝支付金额: " + money);
}
}
public class OverseasPayment implements IPayment {
@Override
public void pay(Double money) {
System.out.println("使用境外支付金额: " + money);
}
}
public class UnionPayment implements IPayment {
@Override
public void pay(Double money) {
System.out.println("使用银联支付金额: " + money);
}
}
public class WechatPayment implements IPayment {
@Override
public void pay(Double money) {
System.out.println("使用微信支付金额: " + money);
}
}
public class PaymentFactory {
public static final String ALI = "ali";
public static final String WECHAT = "wechat";
public static final String UNION = "union";
public static final String OVERSEA = "oversea";
/**
* 創建 支付方式
* @param params
* @return
*/
public static IPayment createPayment(String params) {
if(ALI.equalsIgnoreCase(params)) {
return new AliPayment();
} else if(WECHAT.equalsIgnoreCase(params)) {
return new WechatPayment();
} else if(UNION.equalsIgnoreCase(params)) {
return new UnionPayment();
} else if(OVERSEA.equalsIgnoreCase(params)) {
return new OverseasPayment();
} else {
return null;
}
}
}
public class SimpleFactoryPayTest {
public static void main(String[] args) {
String params = "ali";
IPayment payment = PaymentFactory.createPayment(params);
Double money = 6.2;
payment.pay(money);
}
}
具体类图UML图:
从上面的代码中我们能发现出很多问题
1: 扩展问题, 境外统一支付是后面新接入的接口,如果原理的判断逻辑没有编写的话,那么就需要更改代码判断逻辑,这样做
提高了代码变更造成的风险,违背了开闭原则.
2: 所以的支付都比较抽象,都没有说明是如何支付的,支付的细节没有任何的提现,无法应用到实际中,甚至连参考都谈不上.
既然知道了问题,那么我们就开始对上面的问题做一点改造,改造的引领思路如下:
1: 为了提高扩展性,我们都要习惯性的面向抽象编程.
2: 为了提高扩展性, 我们都要习惯在熟知业务的情况下看看是否可以用设计模式(综合使用设计模式)进行改造.
于是我们对业务场景做出改变,
支付分为国内支付和国外支付,然后国外支付有不同的支付渠道及方式,比如苹果支付,同时国外也有相同的支付方式,支付宝支付,
微信支付,银联支付,这个层面还是对支付方式上面的一个设计,设计如下: (抽象工厂模式)
支付场景设计如下: 在页面上面我们可以选择不同的支付方式,
首先是国内,国外单选框选择,
选择国内: 有如下图显示方式
选择国外: 有如下图显示方式
编写相关代码如下:
public interface IPayment2 {
/**
* 支付金额
* @param money
*/
void pay(Double money);
}
public interface IPaymentFactory {
IPayment2 createAliPayment();
IPayment2 createWechatPayment();
IPayment2 createUnionPayment();
}
public class AbstractFactoryTest {
public static void main(String[] args) {
HomePaymentFacotry homePaymentFacotry = new HomePaymentFacotry();
Double money = 7.8;
homePaymentFacotry.createAliPayment().pay(money);
ForeignPaymentFacotry foreignAliPayment = new ForeignPaymentFacotry();
foreignAliPayment.createAliPayment().pay(money);
foreignAliPayment.createApplePayment().pay(money);
}
}
public class ForeignAliPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国外支付宝支付金额: " + money);
}
}
public class ForeignApplePayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国外苹果宝支付金额: " + money);
}
}
public class ForeignPaymentFacotry implements IPaymentFactory{
@Override
public IPayment2 createAliPayment() {
return new ForeignAliPayment();
}
@Override
public IPayment2 createWechatPayment() {
return new ForeignWechatPayment();
}
@Override
public IPayment2 createUnionPayment() {
return new ForeignUnionPayment();
}
//扩展出 苹果支付
public IPayment2 createApplePayment() {
return new ForeignApplePayment();
}
}
public class ForeignUnionPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国外银联支付金额: " + money);
}
}
public class ForeignWechatPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国外微信支付金额: " + money);
}
}
public class HomeAliPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国内支付宝支付金额: " + money);
}
}
public class HomePaymentFacotry implements IPaymentFactory {
@Override
public IPayment2 createAliPayment() {
return new HomeAliPayment();
}
@Override
public IPayment2 createWechatPayment() {
return new HomeWechatPayment();
}
@Override
public IPayment2 createUnionPayment() {
return new HomeUnionPayment();
}
}
public class HomeUnionPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国内银联支付金额: " + money);
}
}
public class HomeWechatPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国内微信支付金额: " + money);
}
}
导出UML类图如下:
如果要在跨境支付(国外支付)下面添加一个PayPal, 直接新增一个类: PayPalPayment,
public class ForeignPayPalPayment implements IPayment2 {
@Override
public void pay(Double money) {
System.out.println("国外使用PayPal支付金额: " + money);
}
}
修改代码:
public class ForeignPaymentFacotry implements IPaymentFactory{
@Override
public IPayment2 createAliPayment() {
return new ForeignAliPayment();
}
@Override
public IPayment2 createWechatPayment() {
return new ForeignWechatPayment();
}
@Override
public IPayment2 createUnionPayment() {
return new ForeignUnionPayment();
}
//扩展出 苹果支付
public IPayment2 createApplePayment() {
return new ForeignApplePayment();
}
//新增PayPal支付
public IPayment2 createPayPalPayment() {
return new ForeignPayPalPayment();
}
}
符合开闭原则, 对扩展开放,对修改关闭,只需要新增一个类,新增一个方法即可完成PayPal支付方式的增加.
触类旁通:
支付场景除了涉及到工厂模式还有一系列其他的设计模式,
比如策略模式(对具体的支付算法的封装设计)
比如状态模式(对支付状态的一个设计)
还有一些非常重要的常用的支付业务,
例如聚合支付
涉及到单例模式
涉及到适配器模式
至于以上涉及到的设计模式分析详见下章节.
参考链接:
https://www.cnblogs.com/lyc94620/p/13055116.html
https://blog.csdn.net/wwsl123/article/details/107405452