桥梁模式【Bridge Pattern】,什么是桥梁模式?核心思想?优缺点?主要角色?桥梁模式实现?

目录


设计模式专栏目录(点击进入…)



什么是桥梁模式?

桥梁模式(Bridge Pattern)是一种结构型设计模式,它的目的是将抽象部分与实现部分分离,使它们能够独立地变化。通过这种方式,系统可以在不改变客户端代码的情况下,更容易地扩展和维护。


桥梁模式核心思想

桥梁模式将对象的抽象和实现解耦,二者可以独立地进行扩展和变化。抽象部分不再直接与实现部分绑定,而是通过一个桥接(Bridge)接口与实现部分进行关联。这样,我们可以改变抽象的同时改变实现,而不需要修改二者的代码。


桥梁模式优缺点

优点

(1)分离抽象和实现

实现了抽象与实现的解耦,使得它们可以独立地扩展。

(2)提高系统的可扩展性

可以分别扩展抽象层次和实现层次,互不影响。

(3)符合开闭原则

在不修改已有代码的情况下,可以增加新的抽象类和实现类。

(4)减少子类的数量

通过桥接模式,可以减少因多维度变化而导致的子类爆炸问题。

缺点

(1)增加系统的复杂性

引入了额外的抽象层次,可能会增加系统的复杂性。

(2)需要充分理解设计问题

如果使用不当,可能导致系统设计过于复杂,不利于维护。


桥梁模式主要角色

(1)抽象(Abstraction)

定义了高层次的操作,依赖于实现接口(Implementor)。抽象类中通常包含一个指向实现部分的引用,抽象类并不会具体实现行为,而是通过该引用委托给实现类。

(2)扩展抽象(Refined Abstraction)

继承自抽象类,提供更具体的实现或进一步扩展抽象功能。

(3)实现接口(Implementor)

为实现部分定义接口,通常包含一些基础操作,这些操作将被具体的实现类实现。抽象部分通过实现接口来与具体实现交互。

(4)具体实现类(Concrete Implementor)

实现实现接口中的操作,这些是实际执行的功能。


桥梁模式的应用场景?

桥梁模式的适用场景主要集中在需要将抽象和实现解耦的场景,尤其是系统的抽象和实现部分可能会随着时间变化的情况。

(1)当系统需要在抽象和实现之间添加更多的灵活性时

如果一个类存在多个维度的变化,将抽象与实现分离可以让两者独立扩展。例如,假设你有一个图形类,它可以绘制不同类型的形状(如圆形和正方形),而且它们可以使用不同的颜色进行绘制。在这种情况下,你可以通过桥梁模式将“形状”和“颜色”两个维度分离。

(2)当不希望在抽象类中直接实现功能时

桥梁模式将实现部分独立出来,通过接口的方式进行关联,从而实现抽象类与实现类的解耦,提升了灵活性。

(3)当系统需要在不同的硬件或操作系统平台之间进行切换时

桥梁模式可以用于跨平台的应用程序开发,不同的实现类可以适应不同的平台或设备,而抽象部分保持不变。


桥梁模式实现

梦想中的自己,身价过亿,有两个大公司,一个是房地产公司,一个是服装制造业,这两个公司都很赚钱,天天帮我在累加财富,其实是什么公司倒是不关心,我关心的是是不是在赚钱,赚了多少,这才是我关心的,我是商人呀,唯利是图是我的本性,偷税漏税是我的方法,欺上瞒下、压榨员工血汗
我是的手段嘛。

在这里插入图片描述

类图很简单,声明了一个 Corp 抽象类,定义一个公司的抽象模型,公司首要是赚钱的,不赚钱谁开公司,做义务或善举那也是有背后利益支撑的,我还是赞成这句话“天下熙熙,皆为利来;天下壤壤,皆为利往”。

1、定义一个产品的抽象模型

package com.uhhe.common.design.bridge.implementor;

/**
 * 整个集团公司的产品类
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:44
 */
public abstract class Product {

    /**
     * 甭管是什么产品它总要是能被生产出来
     */
    public abstract void produce();

    /**
     * 生产出来的东西,一定要销售出去,否则扩本呀
     */
    public abstract void sell();

}

2、具体的产品(衣服、房子】山寨机iPod)

(1)衣服

package com.uhhe.common.design.bridge.implementor;

/**
 * 集团公司生产的衣服
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:50
 */
public class Clothes extends Product {

    @Override
    public void produce() {
        System.out.println("生产出的衣服是这个样子的...");
    }

    @Override
    public void sell() {
        System.out.println("生产出的衣服卖出去了...");
    }

}

(2)房子

package com.uhhe.common.design.bridge.implementor;

/**
 * 集团公司盖的房子
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:49
 */
public class House extends Product {

    /**
     * 豆腐渣就豆腐渣呗,好歹也是个房子
     */
    @Override
    public void produce() {
        System.out.println("生产出的房子是这个样子的...");
    }

    /**
     * 虽然是豆腐渣,也是能够销售出去的
     */
    @Override
    public void sell() {
        System.out.println("生产出的房子卖出去了...");
    }

}

(3)山寨机iPod

package com.uhhe.common.design.bridge.implementor;

/**
 * 生产iPod了
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:51
 */
public class IPod extends Product {

    @Override
    public void produce() {
        System.out.println("生产出的iPod是这个样子的...");
    }

    @Override
    public void sell() {
        System.out.println("生产出的iPod卖出去了...");
    }

}

4、定义一个公司的抽象模型

package com.uhhe.common.design.bridge.abstraction;

import com.uhhe.common.design.bridge.implementor.Product;

/**
 * 定义一个公司的抽象模型,公司首要是赚钱的,不赚钱谁开公司,做义务或善举那也是有背后利益支撑的
 * 天下熙熙,皆为利来;天下壤壤,皆为利往
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:37
 */
public abstract class Corp {

    /**
     * 定义一个产品对象,抽象的了,不知道具体是什么产品
     */
    private final Product product;

    /**
     * 构造函数,由子类定义传递具体的产品进来
     *
     * @param product 产品
     */
    public Corp(Product product) {
        this.product = product;
    }

    /**
     * 公司是干什么的?赚钱的呀,不赚钱傻子才干
     */
    public void makeMoney() {
        // 每个公司都是一样,先生产
        this.product.produce();
        // 然后销售
        this.product.sell();
    }

}

4、具体的公司(服装、房地产、山寨公司)

(1)服装公司

package com.uhhe.common.design.bridge.abstraction;

import com.uhhe.common.design.bridge.implementor.Clothes;

/**
 * 服装公司,这个行当现在不怎么样
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:41
 */
public class ClothesCorp extends Corp {

    /**
     * 构造函数,由子类定义传递具体的产品进来
     *
     * @param clothes 衣服
     */
    public ClothesCorp(Clothes clothes) {
        super(clothes);
    }

    @Override
    public void makeMoney(){
        super.makeMoney();
        System.out.println("服装公司赚大钱了...");
    }

}

(2)房地产公司

package com.uhhe.common.design.bridge.abstraction;

import com.uhhe.common.design.bridge.implementor.House;

/**
 * 房地产公司,按照翻译来说应该叫realty corp,这个是比较准确的翻译
 * * 但是我问你房地产公司翻译成英文,你第一反应什么?对嘛还是house corp!
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:39
 */
public class HouseCorp extends Corp {

    /**
     * 定义传递一个House产品进来
     *
     * @param house 产品
     */
    public HouseCorp(House house) {
        super(house);
    }

    @Override
    public void makeMoney(){
        super.makeMoney();
        System.out.println("房地产公司赚大钱了...");
    }

}

(3)山寨公司

package com.uhhe.common.design.bridge.abstraction;

import com.uhhe.common.design.bridge.implementor.Product;

/**
 * 山寨公司
 * 我是山寨老大,你流行啥我就生产啥
 *
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:54
 */
public class ShanZhaiCorp extends Corp {

    /**
     * 产什么产品,不知道,等被调用的才知道
     *
     * @param product 产品
     */
    public ShanZhaiCorp(Product product) {
        super(product);
    }

    /**
     * 狂赚钱
     */
    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("我赚钱呀...");
    }

}

5、使用桥梁模式

package com.uhhe.common.design.bridge;

import com.uhhe.common.design.bridge.abstraction.HouseCorp;
import com.uhhe.common.design.bridge.abstraction.ShanZhaiCorp;
import com.uhhe.common.design.bridge.implementor.Clothes;
import com.uhhe.common.design.bridge.implementor.House;
import com.uhhe.common.design.bridge.implementor.IPod;

/**
 * @author nizhihao
 * @version 1.0.0
 * @date 2023/2/28 13:42
 */
public class Client {

    /**
     * 桥梁模式【Bridge Pattern】
     * 桥梁模式的优点就是类间解耦,两个角色都可以自己的扩展下去,不会相互影响,这个也符合 OCP 原则。
     * <p>
     * <p>
     * <p>
     * 桥梁模式的几个概念熟悉一下,大家有没有注意到我把Corp类以及它的两个实现类放到了Abstraction包中,
     * 把House以及相关的三个实现类放到了 Implementor 包中
     * 这两个包分别对应了桥梁模式的 业务抽象角色(Abstraction)和 业务实现角色(Implementor)
     * <p>
     * <p>
     * 现在只有房地产公司和山寨公司,那以后我会不会增加一些其他的公司呢?
     * 或者房地产公司会不会对业务进行细化,比如:分为公寓房公司、别墅公司、以及商业房公司等等呢?
     * 那我告诉你,会的,绝对的会的,但是你发觉没,这种变化对我们上面的类图没有大的修改,充其量是扩展,
     * 你看呀:
     * ①增加公司,你要么继承 Corp 类,要么继承 HouseCorp 或 ShanZhaiCorp,不用再修改原有的类了;
     * ②增加产品,继承 Product 类,或者继承 House 类,你要把房子分为公寓房、别墅、商业用房等等;
     * 你现在都是在扩展,唯一你要修改的就是 Client 类,你类都增加了哪能不修改调用呢,也就是说 Corp 类和
     * Product 类都可以自由的扩展,而不会对整个应用产生太的变更,这就是桥梁模式。
     * <p>
     * 对类的继承有什么看法吗?
     * 继承的优点有很多,可以把公共的方法或属性抽取,父类封装共性,子类实现特性,这是继承的基本功能
     * <p>
     * 缺点有没有?
     * 有,强关联关系,父类有个方法,子类也必须有这个方法,是不可选择的,那这会带来扩展性的问题
     * <p>
     * 举个简单的例子来说明这个问题:
     * Father 类有一个方法 A,Son 继承了这个方法,然后 GrandSon 也继承了这个方法,问题是突然有一天 Son
     * 要重写父类的这个方法,他敢做吗?绝对不敢!GrandSon 可是要用从 Father 继承过来的方法 A,你修改了,
     * 那就要修改 Son 和 GrandSon 之间的关系,那这个风险就大了去。
     * <p>
     * 桥梁模式就是这一问题的解决方法,桥梁模式描述了类间弱关联关系,还说上面的那个例子,
     * Father 类完全可以把可能会变化的方法放出去,Son 子类要有这个方法很简答,桥梁搭过去,获得这个方法,
     * GrandSon 也一样,即使你 Son 子类不想使用这个方法了,也没关系,对 GrandSon 不产生影响,他不是从你 Son 中继承来的方法。
     * <p>
     * 对于比较明确不发生变化的,则通过继承来完成,若不能确定是否会发生变化的,那就认为是会发生变化,则通过桥梁模式来解决
     */
    public static void main(String[] args) {
        House house = new House();
        System.out.println("-------房地产公司是这个样子运行的-------");
        // 先找到我的公司
        HouseCorp houseCorp = new HouseCorp(house);
        // 看我怎么挣钱
        houseCorp.makeMoney();

        System.out.println("\n");
        System.out.println("-------山寨公司是这样运行的-------");
        ShanZhaiCorp shanZhaiCorp = new ShanZhaiCorp(new Clothes());
        shanZhaiCorp.makeMoney();

        System.out.println("\n");
        System.out.println("-------山寨公司是这样运行的-------");
        ShanZhaiCorp shanZhaiCorp1 = new ShanZhaiCorp(new IPod());
        shanZhaiCorp1.makeMoney();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未禾

您的支持是我最宝贵的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值