设计模式系列| 桥接模式

大家好,我是狼王,一个爱打球的程序员

这是设计模式的第八篇,这篇让我们来认识一下桥接模式


1、概述

桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。

2、适用场景

1)如果你想要拆分或重组一个具有多重功能的庞杂类 , 可以使用桥接模式。2) 如果你希望在几个独立维度上扩展一个类, 可使用该模式。对象的属性有其他类去实现,不需要自己处理所有工作。3)如果你需要在运行时切换不同实现方法, 可使用桥接模式。桥接模式可替换抽象部分中的实现对象, 具体操作就和给成员变量赋新值一样简单。

3、实例

有以下场景:

支付途径:微信,支付宝
支付方式:指纹,扫脸

3.1 不使用桥接模式

定义两个枚举

/**
 * 支付方式
 */
public enum PayMethodEnum {

    FACE(0, "扫脸"),
    FINGER(1, "指纹");


    PayMethodEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getName(int code) {
        PayMethodEnum[] payWaysEnums = values();
        for (PayMethodEnum payMethodEnum : payWaysEnums) {
            if (payMethodEnum.code == code) {
                return payMethodEnum.name;
            }
        }
        return null;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int code;

    private String name;

}
/**
 * 支付途径
 */
public enum PayWaysEnum {

    ZHIFUBAO(0, "支付宝"),
    WEIXIN(1, "微信");


    PayWaysEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    private int code;


    public void setName(String name) {
        this.name = name;
    }

    public String getName(int code) {
        PayWaysEnum[] payWaysEnums = values();
        for (PayWaysEnum payWaysEnum : payWaysEnums) {
            if (payWaysEnum.code == code) {
                return payWaysEnum.name;
            }
        }
        return null;
    }

    private String name;

}

定义支付业务流程:

public class Pay {

    public void pay(int payMethod, int payWay) {
        if (PayMethodEnum.FACE.getCode() == payMethod) {
            System.out.println("当前支付方式是:" + PayMethodEnum.FACE.getName(payMethod));
        } else {
            System.out.println("当前支付方式是:" + PayMethodEnum.FINGER.getName(payMethod));
        }
        if (PayWaysEnum.ZHIFUBAO.getCode() == payWay) {
            System.out.println("当前支付途径是:" + PayWaysEnum.ZHIFUBAO.getName(payWay));
        } else {
            System.out.println("当前支付途径是:" + PayWaysEnum.WEIXIN.getName(payWay));
        }
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class TestDemo {

    @Test
    public void test() {
        Pay pay = new Pay();
        //支付宝扫脸支付
        pay.pay(PayMethodEnum.FACE.getCode(),PayWaysEnum.ZHIFUBAO.getCode());
        System.out.println("--------------------------------------");
        //微信扫脸支付
        pay.pay(PayMethodEnum.FACE.getCode(),PayWaysEnum.WEIXIN.getCode());
        System.out.println("--------------------------------------");
        //支付宝指纹支付
        pay.pay(PayMethodEnum.FINGER.getCode(),PayWaysEnum.ZHIFUBAO.getCode());
        System.out.println("--------------------------------------");
        //微信指纹支付
        pay.pay(PayMethodEnum.FINGER.getCode(),PayWaysEnum.WEIXIN.getCode());
        System.out.println("--------------------------------------");
    }

}

结果:

当前支付方式是:扫脸
当前支付途径是:支付宝
--------------------------------------
当前支付方式是:扫脸
当前支付途径是:微信
--------------------------------------
当前支付方式是:指纹
当前支付途径是:支付宝
--------------------------------------
当前支付方式是:指纹
当前支付途径是:微信
--------------------------------------

3.2 使用桥接模式

定义枚举:

/**
 * 支付方式
 */
public enum PayMethodEnum {

    FACE(0, "扫脸"),
    FINGER(1, "指纹");


    PayMethodEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int code;

    private String name;

}
/**
 * 支付途径
 */
public enum PayWaysEnum {

    ZHIFUBAO(0, "支付宝"),
    WEIXIN(1, "微信");


    PayWaysEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    private int code;


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    private String name;

}

定义两个顶层抽象接口:

/**
 * 支付方式接口
 */
public interface IPayMethod {

    void pay();
}
/**
 * 支付途径接口
 */
public interface IPayWay {

    void pay();
}

定义两种支付方式:

/**
 * 指纹
 */
public class FingerPay implements IPayMethod {

    @Override
    public void pay() {
        System.out.println("当前支付方式是:" + PayMethodEnum.FINGER.name());
    }
}
/**
 * 扫脸
 */
public class FacePay implements IPayMethod {

    @Override
    public void pay() {
        System.out.println("当前支付方式是:" + PayMethodEnum.FACE.name());
    }
}

定义两种支付途径:

/**
 * 微信
 */
public class WXPayWay implements IPayWay {

    private IPayMethod payMethod;

    public WXPayWay(IPayMethod payMethod) {
        this.payMethod = payMethod;
    }

    @Override
    public void pay() {
        System.out.println("当前支付方式是:" + PayWaysEnum.WEIXIN.getName());
        payMethod.pay();
    }
}
/**
 * 支付宝
 */
public class ZFBPayWay implements IPayWay {

    private IPayMethod payMethod;

    public ZFBPayWay(IPayMethod payMethod) {
        this.payMethod = payMethod;
    }

    @Override
    public void pay() {
        System.out.println("当前支付方式是:" + PayWaysEnum.ZHIFUBAO.getName());
        payMethod.pay();
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class TestDemo {

    @Test
    public void test() {
        FacePay facePay = new FacePay();
        FingerPay fingerPay = new FingerPay();
        ZFBPayWay zfbPayFace = new ZFBPayWay(facePay);
        WXPayWay wxPayWayFace = new WXPayWay(facePay);
        ZFBPayWay zfbPayFinger = new ZFBPayWay(fingerPay);
        WXPayWay wxPayWayFinger = new WXPayWay(fingerPay);
        //支付宝扫脸支付
        zfbPayFace.pay();
        System.out.println("--------------------------------------");
        //微信扫脸支付
        wxPayWayFace.pay();
        System.out.println("--------------------------------------");
        //支付宝指纹支付
        zfbPayFinger.pay();
        System.out.println("--------------------------------------");
        //微信指纹支付
        wxPayWayFinger.pay();
        System.out.println("--------------------------------------");
    }

}

结果:

当前支付方式是:支付宝
当前支付方式是:FACE
--------------------------------------
当前支付方式是:微信
当前支付方式是:FACE
--------------------------------------
当前支付方式是:支付宝
当前支付方式是:FINGER
--------------------------------------
当前支付方式是:微信
当前支付方式是:FINGER
--------------------------------------

4、分析

如上两种方式都实现了四种支付的过程,其中是以支付途径(支付宝、微信)为主,包含两种支付方式(扫脸、指纹)。

从代码量分析:

不使用:代码还是比较少的,但是其实主要业务逻辑要卸载Pay这个类中,通过if,else判断进行业务逻辑的判断。

使用:代码量大量提升,增加了很多个类,但是pay的业务逻辑只会在自己的类中执行,符合单一职责。

从可扩展层面,假如增加云闪付支付途径:

不使用:需要修改Pay类,增加云闪付的逻辑判断,不符合开闭原则。

使用:只需要增加一个云闪付支付途径即可,不需要修改其他业务逻辑,符合开闭原则。

代码耦合层面:

不使用:代码业务逻辑耦合在一起。

使用的:代码耦合性极低。

5、总结

优点:

1)客户端仅仅与高层抽象进行互动,不关系内部对象。2)符合单一原则。3)符合开闭原则。

缺点:

在业务对象很多,能抽象很多的业务逻辑而言,会大量的增加类的数量,导致代码的复杂性。

乐于输出干货的Java技术公众号:狼王编程。公众号内有大量的技术文章、海量视频资源、精美脑图,不妨来关注一下!回复资料领取大量学习资源和免费书籍!

转发朋友圈是对我最大的支持!

 觉得有点东西就点一下“赞和在看”吧!感谢大家的支持了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值