• 【设计模式】28.结构型模式-桥接(Bridge)


    一、描述

    将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度

    角色:

    1.抽象化角色:给出定义,并保存一个对实现化对象的引用。

    2.扩展抽象化角色:扩展抽象化角色、改变和扩展父类对抽象化的定义

    3.实现化角色:这个角色给出实现化角色的接口,但不给出具体的实现,必须指出的是,这个接口不一定和抽象化角色的接口定义相同。实际上,这两个接口可以非常不一样,实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作

    4.具体实现化角色:这个角色给出实现化角色接口的具体实现
      在这里插入图片描述

    二、优点

    1.分离抽象接口及其实现部分,提高了比继承更好的解决方案。

    2.桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。

    3.实现细节对客户透明,可以对用户隐藏实现细节

    三、缺点

    1.桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开放着针对抽象进行设计与编程。

    2.桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

    四、使用场景

    1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的集成联系,通过桥接模式可以使它们在抽象层建立一个关联关系

    2.对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

    3.一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

    五、示例

    以“顾客吃饭为例”,顾客的目的是方便面以及冰红茶,这两种产品有两种品牌:康师傅和统一。品牌即扩展属性。

    类图:
      在这里插入图片描述

    1.Food类(食物)

    public interface Food {
        /**
         * 吃饭
         */
        void eat();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.InstantNoodles(方便面)

    public class InstantNoodles implements Food {
        //品牌
        private Brand brand;
    
        //初始化品牌
        public InstantNoodles(Brand brand) {
            this.brand = brand;
        }
    
        @Override
        public void eat() {
            brand.brand();
            System.out.println("方便面");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.IceTea(冰红茶)

    public class IceTea implements Food {
        private Brand brand;
    
        public IceTea(Brand brand) {
            this.brand = brand;
        }
    
        @Override
        public void eat() {
            brand.brand();
            System.out.println("冰红茶");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.Brand (品牌接口类)

    public interface Brand {
        /**
         * 定义品牌
         */
        void brand();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.KangShiFu(康师傅)

    public class KangShiFu implements Brand{
        @Override
        public void brand() {
            System.out.println("康师傅牌子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6.TongYi(统一)

    public class TongYi implements Brand{
        @Override
        public void brand() {
            System.out.println("统一牌子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7.Client(顾客)

    public class Client {
        public static void main(String[] args) {
            //吃统一方便面
            InstantNoodles instantNoodles = new InstantNoodles(new TongYi());
            instantNoodles.eat();
    
    
            //喝康师傅冰红茶
            System.out.println();
            IceTea iceTea = new IceTea(new KangShiFu());
            iceTea.eat();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试效果:
    在这里插入图片描述

  • 相关阅读:
    算法 二叉树的遍历(迭代法/递归法)
    模拟计划准备
    教程图文详解 - 广域网通信(第三章)
    PBI 背景全屏规律呈现水印
    备战2024秋招面试题-对比Java、Go和Python
    java基于ssm的网上购物商城系统
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[6]比特币脚本
    解决台式机麦克风不可用问题,只有音频输出,无音频输入
    一幅长文细学JavaScript(七)——一幅长文系列
    图像处理:以图像分类和图像深度估计为例,如何将研究想法进行迁移学习应用?
  • 原文地址:https://blog.csdn.net/CAT_cwds/article/details/126937142