Java设计模式之桥接模式

61 阅读2分钟

桥接模式:抽象实现解耦,使得两者可以独立地变化

上面的话有点难以理解,我们换一种表达方式,我们在日常生活中经常涉及金钱交易,我们如果按支付方式可以分为:银行卡支付、微信支付、支付宝支付等;如果按照支付模式,可以分为:一次性支付、分期付款等,他们之间可以相互组合,如果我们按照一对一的方式组合(这里是指具体类一对一),那么除去两个抽象类,一共有 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 中接口的出现主要还是为了解决单继承机制问题

一图胜前言,在没有使用桥接模式之前,我们的组合方式如下:

image-20230609213658061

而架构是这样的

image-20230609214100961

类图就更不需要说了,光是上层就是需要 2 个高层次模块 + 具体实现类 m + n 个模块 + 组合类 m\times n 个模块,相当冗余,使用桥接模式就可以化繁为简,结构也更为清晰,类图如下:

image-20230609222123276

代码实现

 /**
  * 实现接口
  */
 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();