当前位置: 首页 > news >正文

java 设计模式之桥梁模式

1.引言

SEC安全系统是一家生产和组装汽车产品的安全和电子公司。它提供任何你想要的汽车电子或安全系统,从安全气囊到GPS跟踪系统,倒车停车系统等。大型汽车公司在他们的汽车中使用它的产品。公司使用一种定义良好的面向对象的方法,使用他们开发和维护的软件来跟踪他们的产品。他们得到汽车,为它生产系统,然后把它组装到汽车上。

最近,他们接到了Bigwheel(一家汽车公司)的新订单,为他们的新XZ车型生产中控锁和齿轮锁系统。为了维护这一点,他们正在创建一个新的软件系统。他们首先创建了一个新的抽象类 CarProductSecurity,在这个类中保留了一些特定于汽车的方法和一些他们认为对所有安全产品都通用的特性。然后他们扩展了类并创建了两个不同的子类,分别命名为BigWheelXZCentralLockingBigWheelXZGearLocking。类图如下所示:

过了一会儿,另一家汽车公司Motoren要求他们为他们的LM车型生产一种新的中控锁和齿轮锁系统。由于相同的安全系统不能用于不同车型的两种车型,因此SEC安全系统已经为它们生产了新的系统,并已创建了新的等级MotorEnlmCentrallockingMotorEnlmGearLocking,这也扩展了CarProductSecurity等级。 现在,新的类图如下所示:

到目前为止还不错,但如果另一家汽车公司需要另一套新的中控锁和齿轮锁系统,会发生什么呢?一个需要为它创建另外两个新类。这种设计将为每个系统创建一个类,或者更糟的是,如果为这两个汽车公司中的每一个生产反向停车系统,则将为每个公司再创建两个新类。

子类太多的设计不灵活,难以维护。继承还将实现永久绑定到抽象,这使得独立地修改、扩展和重用抽象和实现变得困难。

请注意,为了使软件系统易于扩展和重用,汽车和产品应独立变化。

桥梁设计模式可以解决这个问题,但在此之前,让我们先了解一些关于桥梁模式的细节。

2.什么是桥梁模式

桥梁模式的目的是将抽象从其实现中分离出来,这样两个抽象就可以独立变化。它将抽象和实现放在两个不同的类层次结构中,以便两者都可以独立扩展。

桥梁的组成部分包括抽象、精抽象、实现者和具体实现者。 抽象定义了抽象的接口,还维护了对类型为实现者的对象的引用,抽象和实现者之间的链接称为桥。

3.实例

在上面讨论的问题中,我们不需要为每个汽车模型的每个产品创建子类,而是可以将设计分为两个不同的层次结构。一个接口用于将用作实现者的产品,另一个接口将是汽车类型的抽象。实现者将由具体的实现者实现,并为其提供实现。另一方面,抽象将通过更精细的抽象来扩展。

package com.javacodegeeks.patterns.bridgepattern;
public interface Product {
    public String productName();
    public void produce();
}
复制代码

实现者产品有一个方法product(),具体实现者将使用该方法为其提供具体的功能。该方法将生成产品的基本模型,经过特定于该车型的一些修改后,可以与任何车型一起使用。

package com.javacodegeeks.patterns.bridgepattern;
public class CentralLocking implements Product{
    private final String productName;
    public CentralLocking(String productName){
        this.productName = productName;
    }
    @Override
    public String productName() {
        return productName;
    }
    @Override
    public void produce() {
        System.out.println("Producing Central Locking System");
    }
 
}
 
package com.javacodegeeks.patterns.bridgepattern;
public class GearLocking implements Product{
    private final String productName;
    public GearLocking(String productName){
        this.productName = productName;
    }
    @Override
    public String productName() {
        return productName;
    }
    @Override
    public void produce() {
        System.out.println("Producing Gear Locking System");
    }
}
复制代码

两个不同的具体实现者为产品实现者提供实现。 现在抽象Car类,它保存了产品类型的引用,并提供了两个抽象方法produceproduct()assembly()

package com.javacodegeeks.patterns.bridgepattern;
public abstract class Car {
    private final Product product;
    private final String carType;
    public Car(Product product,String carType){
        this.product = product;
        this.carType = carType;
    }
    public abstract void assemble();
    public abstract void produceProduct();
    public void printDetails(){
        System.out.println("Car: "+carType+", Product:"+product.productName());
    }
}
复制代码

Car的子类将为assembly()produceProduct()方法提供具体的具体实现。

package com.javacodegeeks.patterns.bridgepattern;
public class BigWheel extends Car{
    private final Product product;
    private final String carType;
    public BigWheel(Product product, String carType) {
        super(product, carType);
        this.product = product;
        this.carType = carType;
    }
 
    @Override
    public void assemble() {
        System.out.println("Assembling "+product.productName()+" for "+carType);
    }
 
    @Override
    public void produceProduct() {
        product.produce();
        System.out.println("Modifing product "+product.productName()+" according to "+carType);
    }
 
}
 
package com.javacodegeeks.patterns.bridgepattern;
public class Motoren extends Car{
    private final Product product;
    private final String carType;
    public Motoren(Product product, String carType) {
        super(product, carType);
        this.product = product;
        this.carType = carType;
    }
 
    @Override
    public void assemble() {
        System.out.println("Assembling "+product.productName()+" for "+carType);
    }
 
    @Override
    public void produceProduct() {
        product.produce();
        System.out.println("Modifing product "+product.productName()+" according to "+carType);
    }
 
}
复制代码

现在,让我们测试这个例子。

package com.javacodegeeks.patterns.bridgepattern;
 
public class TestBridgePattern {
 
    public static void main(String[] args) {
        Product product = new CentralLocking("Central Locking System");
        Product product2 = new GearLocking("Gear Locking System");
        Car car = new BigWheel(product , "BigWheel xz model");
        car.produceProduct();
        car.assemble();
        car.printDetails();
         
        System.out.println();
         
        car = new BigWheel(product2 , "BigWheel xz model");
        car.produceProduct();
        car.assemble();
        car.printDetails();
         
        System.out.println("-----------------------------------------------------");
         
        car = new Motoren(product, "Motoren lm model");
        car.produceProduct();
        car.assemble();
        car.printDetails();
         
        System.out.println();
         
        car = new Motoren(product2, "Motoren lm model");
        car.produceProduct();
        car.assemble();
        car.printDetails();
         
    }
 
}
复制代码

上述示例将生成以下输出:

Producing Central Locking System
Modifing product Central Locking System according to BigWheel xz model
Assembling Central Locking System for BigWheel xz model
Car: BigWheel xz model, Product:Central Locking System
 
Producing Gear Locking System
Modifing product Gear Locking System according to BigWheel xz model
Assembling Gear Locking System for BigWheel xz model
Car: BigWheel xz model, Product:Gear Locking System
-----------------------------------------------------
Producing Central Locking System
Modifing product Central Locking System according to Motoren lm model
Assembling Central Locking System for Motoren lm model
Car: Motoren lm model, Product:Central Locking System
 
Producing Gear Locking System
Modifing product Gear Locking System according to Motoren lm model
Assembling Gear Locking System for Motoren lm model
Car: Motoren lm model, Product:Gear Locking System
复制代码

4.什么时候使用桥梁模式

在以下情况下,应使用桥接模式:

  • 您希望避免抽象及其实现之间的永久绑定。
  • 抽象及其实现都应该通过子类进行扩展。在本例中,桥梁模式允许您组合不同的抽象和实现,并独立地扩展它们。
  • 抽象实现中的更改不应对客户机产生影响;也就是说,不必重新编译他们的代码。

转载于:https://juejin.im/post/5d09b08f6fb9a07ead59fea6

相关文章:

  • LeetCode 939. Minimum Area Rectangle
  • js实现天小时分钟秒倒计时
  • Mahout 中基于SVD 的协同过滤原理
  • 抽屉原理
  • Flexigrid自定义显示数据列
  • parseInt()
  • SQL SERVER 2000数据库置疑处理
  • 从零开始--系统深入学习android(实践-让我们开始写代码-Android框架学习-4.Action Bar)...
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • vue组件之间的传值
  • 『Python基础』第二节: Python简介及入门
  • 统一ID服务
  • 小小c#算法题 - 5 - 插入排序
  • 线程启动 [转]
  • PSP Skype 使用国内卡
  • 《剑指offer》分解让复杂问题更简单
  • github从入门到放弃(1)
  • Java IO学习笔记一
  • JavaScript的使用你知道几种?(上)
  • SpiderData 2019年2月13日 DApp数据排行榜
  • 初识 beanstalkd
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从零开始在ubuntu上搭建node开发环境
  • 官方解决所有 npm 全局安装权限问题
  • 数组的操作
  • 学习HTTP相关知识笔记
  • 一个SAP顾问在美国的这些年
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 走向全栈之MongoDB的使用
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​ssh免密码登录设置及问题总结
  • #vue3 实现前端下载excel文件模板功能
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (8)STL算法之替换
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (ZT)一个美国文科博士的YardLife
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (九)One-Wire总线-DS18B20
  • (九)信息融合方式简介
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)jdk与jre的区别
  • (转)Linux下编译安装log4cxx
  • (转)菜鸟学数据库(三)——存储过程
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .net core 依赖注入的基本用发
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET Remoting学习笔记(三)信道
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET 中让 Task 支持带超时的异步等待
  • .net解析传过来的xml_DOM4J解析XML文件
  • .NET与 java通用的3DES加密解密方法