适配器模式(adapter pattern)相当于一种补救手段,在项目开发期基本不会用到。
适配器的核心目的是不改动原有的逻辑,而又可以使用新的函数
首先构建代码场景:
我们项目里有一个支付的模块,支付模块是相对隔离的,即支付后的操作都是一致的。
一开始设计的时候,只想用户用支付宝支付,于是我们这么写
(1)先声明一个支付的接口
public interface Pay {
void payMoney();
}
(2)写一个支付宝支付的实现类
public class Alipay implements Pay {
@Override
public void payMoney() {
System.out.println("使用支付宝支付");
}
}
(3)运行程序
public static void main(String[] args) {
Pay aliPay = new Alipay();
aliPay.payMoney();
}
输出:使用支付宝支付
然后负责写支付模块的哥们A觉得早晚会有微信支付,不如先写了,省的以后麻烦,但他埋了个坑。下面是他的微信支付代码:
public class WeiChatPay {
public void pay() {
System.out.println("使用微信钱包支付");
}
}
他自己写的微信支付,没有实现原来的支付接口,然后项目就这么上线了。过了一段时间,写支付的哥们A辞职了。这时候来了一个新需求,需要支持微信支付,然后哥们B负责项目维护。这时候B才发现A挖的坑,但微信支付实在太复杂了,B又不想再重新写一套,于是他使用了适配器模式。
他是这么做的
(1)
public class PayAdapter1 extends WeiChatPay implements Pay {
@Override
public void payMoney() {
System.out.print("我是适配器1: ");
//很明显,这里调用了微信支付
super.pay();
}
}
(2)然后执行程序
public static void main(String[] args) {
Pay aliPay = new Alipay();
aliPay.payMoney();
Pay weiChatPay1 = new PayAdapter1();
weiChatPay1.payMoney();
输出:
使用支付宝支付
我是适配器1: 使用微信钱包支付
但是B哥们对技术有执着要求,他觉得继承这种方式不好,于是他改进了他的代码,写了第二个适配器类:
(1)
public class PayAdapter2 implements Pay {
@Override
public void payMoney() {
System.out.print("我是适配器2: ");
//很明显,这里调用了微信支付
new WeiChatPay().pay();
}
}
(2)执行程序
public static void main(String[] args) {
Pay aliPay = new Alipay();
aliPay.payMoney();
Pay weiChatPay1 = new PayAdapter1();
weiChatPay1.payMoney();
Pay weiChatPay2 = new PayAdapter2();
weiChatPay2.payMoney();
}
输出:
使用支付宝支付
我是适配器1: 使用微信钱包支付
我是适配器2: 使用微信钱包支付
到此适配器的两种实现都有了。
总结:
(1)首先组合优先于继承,并且如果微信支付类无法被子类化,只能使用组合。PS:可以在组合中使用单例,节省资源
(2)我们使用适配器的目的就是为了让一个Pay应用的对象去完成微信支付,这样,Pay对象出现的地方,我们就可以不用修改。
可以看出如果A哥们如果一开始就实现了支付接口,就不会有后面这么多事了。。。。另外如果A哥们一开始连个接口都没写,那可就好玩了。。。