桥接模式:抽象与实现解耦,使得两者可以独立地变化
上面的话有点难以理解,我们换一种表达方式,我们在日常生活中经常涉及金钱交易,我们如果按支付方式可以分为:银行卡支付、微信支付、支付宝支付等;如果按照支付模式,可以分为:一次性支付、分期付款等,他们之间可以相互组合,如果我们按照一对一的方式组合(这里是指具体类一对一),那么除去两个抽象类,一共有 m\times n 种组合方式
/**
* 支付方式 + 支付模式接口
*/
// 抽象接口
interface PayMethod {
String method();
}
// 实现接口
interface PayPattern {
String pattern();
}
/**
* 支付类
*/
class PayStrategy {
private final PayMethod method;
private final PayPattern pattern;
public PayStrategy(PayMethod method, PayPattern pattern) {
this.method = method;
this.pattern = pattern;
}
public void use() {
System.out.println("我现在使用" + method.method() + "中的" + pattern.pattern() + "的方式进行支付");
}
}
/**
* 具体支付方式 + 具体支付模式
* 这里仅写出两个作为示范
*/
class WeChat implements PayMethod {
public String method() {
return "微信支付";
}
}
class OneTime implements PayPattern {
public String pattern() {
return "一次性支付";
}
}
测试程序
new PayStrategy(new WeChat(), new OneTime()).use();
😅这里偷懒过头了,坏例子应该是两两组合,单独成为一个具体的类,这样除去2个抽象类,一组合就会形成 m \times n 个具体实现类,虽然上述的方式是 m+n+1,将原本二阶级别降为一阶级别,但还是和 "正宗" 的桥接模式有所区别,桥接模式的核心是:解耦抽象和实现,两者通过关联关系建立联系,而不是继承关系,像前面的装饰器也是将继承关系替代为关联关系,只不过桥接模式最终的目的在于实现,而装饰器是为了升级
注意:这里没有区分抽象类和接 口类,其实在 C++ 中也没有接口的概念,Java 中接口的出现主要还是为了解决单继承机制问题
一图胜前言,在没有使用桥接模式之前,我们的组合方式如下:
而架构是这样的
类图就更不需要说了,光是上层就是需要 2 个高层次模块 + 具体实现类 m + n 个模块 + 组合类 m\times n 个模块,相当冗余,使用桥接模式就可以化繁为简,结构也更为清晰,类图如下:
代码实现
/**
* 实现接口
*/
interface PayPattern {
String pay();
}
/**
* 实现类
*/
class OneTime implements PayPattern {
public String pay() {
return "一次性结清";
}
}
class Instalment implements PayPattern {
public String pay() {
return "分期付款";
}
}
/**
* 抽象类
*/
abstract class PayMethod {
protected PayPattern pattern;
public PayMethod(PayPattern pattern) {
this.pattern = pattern;
}
abstract String pay();
public void use() {
System.out.println("我正在使用" + this.pay() + "中的" + pattern.pay() + "作为支付方式");
}
}
/**
* 扩展抽象类
*/
class WeChat extends PayMethod {
public WeChat(PayPattern pattern) {
super(pattern);
}
String pay() {
return "微信";
}
}
class AliPay extends PayMethod {
public AliPay(PayPattern pattern) {
super(pattern);
}
String pay() {
return "支付宝";
}
}
测试程序
PayMethod weChat_OneTime = new WeChat(new OneTime());
PayMethod alipay_Instalment = new AliPay(new Instalment());
weChat_OneTime.use();
alipay_Instalment.use();