Java设计模式 _结构型模式_桥接模式

news2024/11/28 4:48:20

一、桥接模式

1、桥接模式
桥接模式(Bridge Pattern)是一种结构型设计模式。用于把一个类中多个维度的抽象化与实现化解耦,使得二者可以独立变化。

2、实现思路
使用桥接模式,一定要找到这个类中两个变化的维度:如支付功能中(平台类型,支付方式)或带颜色形状(形状,涂色)。
(1)、定义次维度规划抽象和实例方式(支付方式为抽象(接口),密码支付,扫脸支付,指纹支付为三种实例(接口实现类))。
(2)、次维度接口定义规范方法,每一种实现类遵循规范进行各自业务的实现。
(3)、定义主维度抽象类和实现类(支付渠道(抽象类),微信,支付宝(抽象类的实现类))
(4)、在主维度抽象类中,定义次维度的抽象属性,通过构造方法实例化该属性,定义统一的抽象方法(支付方法);
(5)、在主维度实现类中,通过自身方法和次维度属性的实现方法封装各自具体的业务方法。

二、代码示例

1、不使用桥接,直接判断

  // 定义和实现支付方法
 public static String doPay(String payUser,String receiveUser,double money, String payType,String securityMode){
        StringBuilder builder = new StringBuilder("");
        builder.append(payUser);
        if ("wechat".equals(payType)){
            builder.append("使用微信-");
            if ("password".equals(securityMode)){
                builder.append("密码支付");
            } else if("face".equals(securityMode)){
                builder.append("扫脸支付");
            }else if("fingerprint".equals(securityMode)){
                builder.append("指纹支付");
            }
            builder.append(money).append("元");
        }
        if ("alipay".equals(payType)){
            builder.append("使用支付宝-");
            if ("password".equals(securityMode)){
                builder.append("密码支付");
            } else if("face".equals(securityMode)){
                builder.append("扫脸支付");
            }else if("fingerprint".equals(securityMode)){
                builder.append("指纹支付");
            }
            builder.append(money).append("元");
        }
        builder.append("给").append(receiveUser);
        return builder.toString();
    }
    // 测试
    public static void main(String[] args) {
        System.out.println("直接方式");
        String directResult = doPay("张三", "李四", 30, "wechat", "password");
        System.out.println(directResult);
        directResult = doPay("张三", "王五", 10.6, "alipay", "fingerprint");
        System.out.println(directResult);
    }

运行结果:
在这里插入图片描述
说明:上面的示例中,虽然运行得到了正确的结果。但是从代码上看,所有的代码都写到一起,不利于代码管理和阅读;如果扩展支付方式或者支付平台,必然会影响彼此(如:扩展支付类型扫码支付,支付平台的微信和支付宝实现中都需要改造代码;再如:扩展支付平台中行支付,支付方式每一种都需要在新平台的方法中重写一遍),可以看出两个维度是强耦合关系,不符合设计模式的开闭原则。

2、桥接模式示例

// 支付类型接口--次维度抽象规范接口
public interface PayMode {
    String securityPay();
}
// 密码支付--次维度规范实现类1
public class PasswordMode implements PayMode {
    @Override
    public String securityPay() {
        return "密码支付";
    }
}
// 扫脸支付--次维度规范实现类2
public class FaceMode implements PayMode {
    @Override
    public String securityPay() {
        return "扫脸支付";
    }
}
// 指纹支付--次维度规范实现类3
public class FingerprintMode implements PayMode {
    @Override
    public String securityPay() {
        return "指纹支付";
    }
}

// 定义支付平台的抽象--主维度抽象方法
import lombok.Data;
@Data
public abstract class Pay {
    protected String payUser;
    protected String receiveUser;
    protected double money;
    protected PayMode payMode;   // 次维度的抽象属性

    public abstract String doPay();   // 支付方法
}
// 微信--主维度实现类1
public class WeChatPay extends Pay {
    public WeChatPay(Builder builder){
        this.payUser= builder.payUser;
        this.receiveUser= builder.receiveUser;
        this.money= builder.money;
        this.payMode= builder.payMode;
    }

    @Override
    public String doPay() {   // 实现主维度方法
        return payUser+"使用微信-"+payMode.securityPay()+money+"元给"+receiveUser;
    }

    public static class Builder{     // 建造者模式
        private String payUser;
        private String receiveUser;
        private double money;
        private PayMode payMode;
        public Builder setPayUser(String payUser) {
            this.payUser = payUser;
            return this;
        }
        public Builder setReceiveUser(String receiveUser) {
            this.receiveUser = receiveUser;
            return this;
        }
        public Builder setMoney(double money) {
            this.money = money;
            return this;
        }
        public Builder setPayMode(PayMode payMode) {
            this.payMode = payMode;
            return this;
        }
        public WeChatPay build() {
            return new WeChatPay(this);
        }
    }
}
// 支付宝--主维度实现类2
public class AliPayPay extends Pay {
    public AliPayPay(Builder builder){
        this.payUser= builder.payUser;
        this.receiveUser= builder.receiveUser;
        this.money= builder.money;
        this.payMode= builder.payMode;
    }
    @Override
    public String doPay() {  // 实现主维度方法
        return payUser+"使用支付宝-"+payMode.securityPay()+money+"元给"+receiveUser;
    }

    public static class Builder{    // 建造者模式
        private String payUser;
        private String receiveUser;
        private double money;
        private PayMode payMode;
        public Builder setPayUser(String payUser) {
            this.payUser = payUser;
            return this;
        }
        public Builder setReceiveUser(String receiveUser) {
            this.receiveUser = receiveUser;
            return this;
        }
        public Builder setMoney(double money) {
            this.money = money;
            return this;
        }
        public Builder setPayMode(PayMode payMode) {
            this.payMode = payMode;
            return this;
        }
        public AliPayPay build() {
            return new AliPayPay(this);
        }
    }
}
// 测试
 public static void main(String[] args) {
        System.out.println("桥接模式:");
        Pay wechatPay = new WeChatPay.Builder()
                .setPayUser("张三")
                .setReceiveUser("李四")
                .setMoney(20.9)
                .setPayMode(new PasswordMode())
                .build();
        System.out.println(wechatPay.doPay());
        Pay aliPay = new AliPayPay.Builder()
                .setPayUser("张三")
                .setReceiveUser("王五")
                .setMoney(8.9)
                .setPayMode(new FingerprintMode())
                .build();
        System.out.println(aliPay.doPay());
    }

运行结果:
在这里插入图片描述
说明:使用桥接模式,运行结果也满足需求。

3、桥接模式相对于直接调用的好处
1、解耦:使用桥接模式,如果扩展支付类型,仅通过新的类实现PayMode即可,不需要主维度代码修改;如果扩展支付平台,仅通过新的类实现Pay抽象类即可,不需要次维度代码修改;同时相对直接使用,更加准寻开闭原则。
2、代码逻辑更清晰,方便阅读。
3、更好的扩展方式。

但是桥接模式会增家类的定义和实现,一定层度上对框架的复杂度会有提升,所以实际场景还是根据自身情况决定比较好。

学海无涯苦作舟!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1631592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是中间件?中间件有哪些?

什么是中间件? 中间件(Middleware)是指在客户端和服务器之间的一层软件组件,用于处理请求和响应的过程。 中间件是指介于两个不同系统之间的软件组件,它可以在两个系统之间传递、处理、转换数据,以达到协…

[论文笔记]GAUSSIAN ERROR LINEAR UNITS (GELUS)

引言 今天来看一下GELU的原始论文。 作者提出了GELU(Gaussian Error Linear Unit,高斯误差线性单元)非线性激活函数: GELU x Φ ( x ) \text{GELU} x\Phi(x) GELUxΦ(x),其中 Φ ( x ) \Phi(x) Φ(x)​是标准高斯累积分布函数。与ReLU激活函数通过输入…

Spring Web MVC入门(3)——响应

目录 一、返回静态页面 RestController 和 Controller之间的关联和区别 二、返回数据ResponseBody ResponseBody作用在类和方法的情况 三、返回HTML代码片段 响应中的Content-Type常见的取值: 四、返回JSON 五、设置状态码 六、设置Header 1、设置Content…

docker如何生成springboot镜像

1、在springboot的jar包所在的目录下创建Dockerfile文件,此案例的目录为/usr/java Dockerfile的文件内容如下: FROM openjdk:8 LABEL author"zengyanhui" LABEL email"1181159889qq.com" WORKDIR /usr/java/springbootdemo COPY s…

动漫渐显引导页HTML5单页源码

挺不错的动漫渐显引导页,记事本右键打开即可修改~ 动漫渐显引导页HTML5单页源码

重生之我是Nginx服务专家

nginx服务访问页面白色 问题描述 访问一个域名服务返回页面空白,非响应404。报错如下图。 排查问题 域名解析正常,网络通讯正常,绕过解析地址访问源站IP地址端口访问正常,nginx无异常报错。 在打开文件时,发现无法…

179. 最大数(LeetCode)

文章目录 前言一、题目讲解二、算法原理三、代码编写1.仿函数写法2.lambda表达式 四、验证五.总结 前言 在本篇文章中,我们将会带着大家采用贪心的方法解决LeetCode中最大数这道问题!!! 一、题目讲解 一组非负整数,包…

机器学习的指标评价

之前在学校的小发明制作中,在终期答辩的时候,虽然整个项目的流程都答的很流畅。 在老师提问的过程中,当老师问我recall,precision,accuracy等指标是如何计算的,又能够表示模型的哪方面指标做得好。我听到这个问题的时候&#xff…

信息系统项目管理师0076:应用集成(5信息系统工程—5.3系统集成—5.3.5应用集成)

点击查看专栏目录 文章目录 5.3.5应用集成5.3.5应用集成 随着网络和互联网的发展以及分布式系统的日益流行,大量异构网络及各计算机厂商推出的软、硬件产品分布在分布式系统的各层次(如硬件平台、操作系统、网络协议、计算机应用),乃至不同的网络体系结构上都广泛存在着互操…

10.通用定时器

驱动电机 RGB LED亮度(呼吸灯) 舵机(遥控车、机械臂) 通用定时器作用 1.延时 2.定时器更新中断 3.输出比较(PWM波、驱动IO输出波形(脉冲)) 4.输入捕获&…

VMware安装ubuntun虚拟机使用桥接模式无法上网问题解决

问题:最近准备使用VMware虚拟机搭建k8s集群服务,因为需要在同一个网段下,我使用桥接的方式,我发现主机在使用有线连接时虚拟机网络连接正常,但是使用无线网就显示连接不上网络。 解决方法 一、查看网络连接&#xff…

Codeforces Round 941 (Div. 2)(A-D)

A. Card Exchange(思维 Problem - A - Codeforces 题目大意: 给定n张牌,每次选k张相同的牌,把他们变成k-1张任意的牌,求最后手中最少能有几张牌。 思路: 直接判断这n张牌当中有没有k张一样的牌&#xff0c…

Python快速入门1数据类型(需要具有编程基础)

数据类型: Python 3.0版本中常见的数据类型有六种: 不可变数据类型可变数据类型Number(数字)List(列表)String(字符串)Dictionary(字典)Tuple(元…

NLP transformers - 文本分类

Text classification 文章目录 Text classification加载 IMDb 数据集Preprocess 预处理EvaluateTrainInference 本文翻译自:Text classification https://huggingface.co/docs/transformers/tasks/sequence_classification notebook : https://colab.research.googl…

明日周刊-第8期

现在露营的人越来越多了,都是带着帐篷或者遮阳篷聚在一起喝喝茶聊聊天,这是一种很好的放松方式。最近我养了一只金毛,目前两个月大,非常可爱。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 一、人工智能领域 本周&#xff…

Java面试八股之main方法的参数中字符串数组的第一个元素是什么

Java main方法的参数中字符串数组的第一个元素是什么 Java main 方法的参数中字符串数组的第一个参数通常是指命令行启动Java应用程序时传递给该程序的第一个命令行参数。当您在命令行中执行一个Java应用程序,可以跟随类名后面附加一系列参数,这些参数将…

Debian 系统设置SSH 连接时长

问题现象: 通过finalshell工具连接Debian系统远程操作时,总是一下断开一下断开,要反复重新连接 ,烦人! 解决办法: 找到ssh安装目录下的配置文件:sshd_config vi sshd_config : 找到…

李沐70_bert微调——自学笔记

微调BERT 1.BERT滴哦每一个词元返回抽取了上下文信息的特征向量 2.不同的任务使用不同的特性 句子分类 将cls对应的向量输入到全连接层分类 命名实体识别 1.识别应该词元是不是命名实体,例如人名、机构、位置 2.将非特殊词元放进全连接层分类 问题回答 1.给…

Android --- 常见UI组件

TextView 文本视图 设置字体大小:android:textSize"20sp" 用sp 设置颜色:android:textColor"#00ffff" 设置倍距(行距):android:lineSpacingMultiplier"2" 设置具体行距:android:lineSpacingExtra&q…

闲话 ASP.NET Core 数据校验(二):FluentValidation 基本用法

前言 除了使用 ASP.NET Core 内置框架来校验数据,事实上,通过很多第三方框架校验数据,更具优势。 比如 FluentValidation,FluentValidation 是第三方的数据校验框架,具有许多优势,是开发人员首选的数据校验…