文章目录
问题需求(支付系统渠道商的选择问题)
聚合支付项目对接了三个渠道商,分别渠道商A,渠道商B,渠道商C,每个渠道商都有一套独立的对接文档(从商户入驻,到支付,到清算)。那么该如何实现这个功能呢?
问题解决
V1.0版本
V1.0版本就是直接梭哈,将所有的业务逻辑写在了客户端,客户端在调用的时候可以分别调用各个渠道商的商户入驻方法。
public class Client {
public static void main(String[] args) {
Client client = new Client();
client.addCustomerA("商户1");
client.addCustomerB("商户2");
client.addCustomerC("商户3");
}
public String addCustomerA(String customer) {
System.out.println("渠道商A入驻"+customer+"成功");
return "success";
}
public String addCustomerB(String customer) {
System.out.println("渠道商B入驻"+customer+"成功");
return "success";
}
public String addCustomerC(String customer) {
System.out.println("渠道商C入驻"+customer+"成功");
return "success";
}
}
上述代码把策略和调用都放在了客户端中,从中不难看出,如果要在增加一个渠道商的话,则必定要修改客户端 增加新渠道商的商户入驻方法。这样就会导致客户端变得十分臃肿复杂维护起来非常麻烦,同时也没有体现面向对象的设计思想,在实际开发中写出这样的代码怕是要被老板优化。 那么我们该如何优化呢?
v1.1版本
从面向对象的角度出发,每个渠道商抽象成一个具体的对象,用一个单独的类保存其属性和行为,同时公共行为(商户入驻的行为)则用一个接口来定义,每个渠道商的类分别实现这个接口。
- 定义公共的接口Income,该接口主要是规范了各个渠道商的行为,这里通过addCustomer方法定义了商户入驻的行为。
public interface Income {
/\*\*
\* 商户入驻
\* @return
\*/
String addCustomer(String customer);
}
- 定义各个渠道商的类,这里分别定义了MerchantAIncome,MerchantBIncome以及MerchantCIncome 三个渠道商的类,并且这三个类都实现了Income接口的addCustomer方法,实现商户入驻。
public class MerchantAIncome implements Income {
@Override
public String addCustomer(String customer) {
System.out.println("渠道商A入驻"+customer+"成功");
return "success";
}
}
- 定义环境类Context,这里的环境类主要的作用就是持有一个Income对象的引用,并且该Income对象所能操作的各种行为(即各种策略)。
public class Context {
private Income income;
public Context(Income income) {
this.income = income;
}
public String addCustomer(String customer) {
return income.addCustomer(customer);
}
}
- 定义调用客户端
public class Client {
public static void main(String[] args) {
new Context(new MerchantAIncome()).addCustomer("商户1");
new Context(new MerchantBIncome()).addCustomer("商户2");
new Context(new MerchantCIncome()).addCustomer("商户3");
}
}
UML图
上述代码的UML图如下图所示:这里有三个主要的角色:
- 环境类Context
- 抽象的策略Income接口
- 具体的策略MerchantAIncome,MerchantBIncome以及MerchantCIncome这三个类。
如上图所示:每个渠道商的类都是实现了一个公共的接口,该接口定义了渠道商中各种行为,包括商户入驻等等。客户端判断当前使用的是哪个渠道商。然后,生成该渠道商的实例,接着调用该渠道商的相关方法。每个渠道商自身的变化不会影响到客户端。相比较于V1.0版本而言,代码逻辑简洁了很多,增加一个渠道商的话只需要再增加一个渠道商的类,并且在客户端中加上一个判断,符合开闭原则。这里就引出了本文将要介绍的模式----策略模式。
策略模式
定义
策略模式就是定义一系列的算法(对应本例中的一系列渠道商), 将每个算法封装到具有公共接口的一系列策略类中(对应到本例中就是将每个渠道商封装成一个单独的类,并且这些类实现一个公共的接口),从而使它们可以相互替换并且让算法可以在不影响客户端的情况下发生变化。
主要作用
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!