• 桥接模式(Bridge Pattern)


    模式动机

    桥接模式(Bridge Pattern)是一种很实用的结构型模式,如果系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使得两者可以独立扩展。桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多重继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效地控制了系统中类的个数。

    模式定义

    将抽象部分与它的实现部分分离,使它们都可以独立地变化。

    • 对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式
    • 用抽象关联取代了传统的多层继承
    • 将类之间的静态继承关系转换为动态的对象组合关系

    模式结构

    案例实现

    案例背景

    毛笔:颜色和型号实现了分离,增加新的颜色或者型号对另一方没有任何影响

    案例结构

    代码实现

    抽象类

    processing
    public abstract class Pen {
    
        protected Color color;
    
        public void setColor(Color color) {
            this.color = color;
        }
    
        public abstract void draw(String name);
    }

    细化抽象类

    scala
    public class BigPen extends Pen {
        @Override
        public void draw(String name) {
            String penType = "大号毛笔绘制";
            this.color.bepaint(penType,name);
        }
    }
    scala
    public class MiddlePen extends Pen {
    
        @Override
        public void draw(String name) {
            String penType = "中号毛笔绘制";
            this.color.bepaint(penType,name);
        }
    }
    scala
    public class SmallPen extends Pen {
        @Override
        public void draw(String name) {
            String penType = "小号毛笔绘制";
            this.color.bepaint(penType,name);
        }
    }

    接口

    arduino
    public interface Color {
        //用于图形着色的方法
        void bepaint(String penType,String name);
    
    }

    接口实现类

    typescript
    public class Red implements Color {
        @Override
        public void bepaint(String penType, String name) {
            System.out.println(penType+"红色的"+name+".");
        }
    }
    
    public class White implements Color {
        @Override
        public void bepaint(String penType, String name) {
            System.out.println(penType+"白色的"+name+".");
        }
    }
    
    public class Green implements Color {
        @Override
        public void bepaint(String penType, String name) {
            System.out.println(penType+"绿色的"+name+".");
        }
    }
    
    public class Blue implements Color {
        @Override
        public void bepaint(String penType, String name) {
            System.out.println(penType+"蓝色的"+name+".");
        }
    }
    
    public class Black implements Color {
        @Override
        public void bepaint(String penType, String name) {
            System.out.println(penType+"黑色的"+name+".");
        }
    }

    客户类

    processing
    public class Client {
    
        public static void main(String[] args) {
    
            Color color;
            Pen pen;
            color = (Color) XMLUtilPen.getBean("color");
            pen = (Pen) XMLUtilPen.getBean("pen");
    
            pen.setColor(color);
            pen.draw("鲜花");
    
        }
    
    }

    实现结果

    模式分析

    • 桥接模式中体现了很多OOP的思想,包括开闭原则合成复用原则里氏代换原则依赖倒转原则等。
    • 桥接模式可以从接口中分离实现功能,设计更具有扩展性。
    • 桥接模式减少了子类个数,代码简洁。
    • 重点理解如何将抽象化(Abstraction)和实现化(Implementation)脱耦,使得两者可以独立变化。
    • 脱耦
      • 抽象化和实现化之间的耦合解开,或者说是将强关联改换成弱关联,将两个角色之间的继承关系改为关联关系
      • 桥接模式中的所谓脱耦就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合)而不是继承关系,从而使得两者可以相对独立地变化。
      • 继承是强耦合关系。

    总结

    模式优点

    • 分离抽象接口及其实现部分
    • 可以取代多层继承方案,极大地减少了子类的个数
    • 提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,不需要修改原有系统,符合开闭原则

    模式缺点

    • 会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就要针对抽象层进行设计与编程
    • 正确识别出系统中两个独立变化的维度并不是一件容易的事情

    应用情形

    • 需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系
    • 抽象部分和实现部分可以以继承的方式独立扩展而互不影响
    • 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立地进行扩展
    • 不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统

    模式扩展

    桥接模式与适配器模式经常联合使用,适配器模式可以解决两个已有接口间不兼容的问题,适配器采用增加适配器的方式将第三方类集成到系统中;而桥接模式则通过接口继承或者类继承的方式对系统进行扩展。两个模式用于设计的不同阶段,通常情况下桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个角色,使它们可以分别进行变化。初步设计完成后,当发现系统与已有类无法协同工作时,可以采用适配器模式。


    __EOF__

  • 本文作者: Coder 街酒
  • 本文链接: https://www.cnblogs.com/sorrymine/p/17418594.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    MR导游情景英语虚拟仿真实训系统应用
    深入实现 MyBatis 底层机制的实现任务阶段 7- 实现动态代理 Mapper 的方法
    Vue页面路由参数的传递和获取
    vue3接口、数据懒加载,回滚不重复加载
    uniapp-父向子组件传值失效解决方案
    rust OJ实战
    MarkDown语法超详细讲解
    SpringCloud无介绍快使用,gateway通过微服务名实现动态路由(十七)
    More types: structs, slices, and maps Part3
    487. 金明的预算方案
  • 原文地址:https://www.cnblogs.com/sorrymine/p/17418594.html