(八)结构型模式-桥接模式

itmahy
itmahy
发布于 2024-01-19 / 29 阅读
0
0

(八)结构型模式-桥接模式

桥接模式

将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体模式或接口模式。

官方定义非常精准、简练,但却有点不易理解。通俗地说,如果一个对象有两种或者多种分类方式,并且两种分类方式都容易变化,比如本例中的形状和颜色。这时使用继承很容易造成子类越来越多,所以更好的做法是把这种分类方式分离出来,让他们独立变化,使用时将不同的分类进行组合即可。

说到这里,不得不提一个设计原则:合成 / 聚合复用原则。虽然它没有被划分到六大设计原则中,但它在面向对象的设计中也非常的重要。

合成 / 聚合复用原则:优先使用合成 / 聚合,而不是类继承。

继承虽然是面向对象的三大特性之一,但继承会导致子类与父类有非常紧密的依赖关系,它会限制子类的灵活性和子类的复用性。而使用合成 / 聚合,也就是使用接口实现的方式,就不存在依赖问题,一个类可以实现多个接口,可以很方便地拓展功能。

举例

考虑这样一个需求:绘制矩形、圆形、三角形这三种图案。按照面向对象的理念,我们至少需要三个具体类,对应三种不同的图形。

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:26
 * @Description: 形状接口
 */
public interface Shape {
​
    /**
     * 画图形
     */
    void draw();
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:25
 * @Description: 圆形实现类
 */
public class Round implements Shape{
​
    @Override
    public void draw() {
        System.out.println("绘制圆");
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:27
 * @Description: 矩形实现类
 */
public class Rectangle implements Shape{
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:28
 * @Description: 三角形实现类
 */
public class Triangle implements Shape{
​
    @Override
    public void draw() {
        System.out.println("绘制三角形");
    }
}

接下来我们有了新的需求,每种形状都需要有四种不同的颜色:红、蓝、黄、绿。

这时我们很容易想到两种设计方案:

  • 为了复用形状类,将每种形状定义为父类,每种不同颜色的图形继承自其形状父类。此时一共有 12 个类。

  • 为了复用颜色类,将每种颜色定义为父类,每种不同颜色的图形继承自其颜色父类。此时一共有 12 个类。

乍一看没什么问题,我们使用了面向对象的继承特性,复用了父类的代码并扩展了新的功能。

但仔细想一想,如果以后要增加一种颜色,比如黑色,那么我们就需要增加三个类;如果再要增加一种形状,我们又需要增加五个类,对应 5 种颜色。

更不用说遇到增加 20 个形状,20 种颜色的需求,不同的排列组合将会使工作量变得无比的庞大。看来我们不得不重新思考设计方案。

形状和颜色,都是图形的两个属性。他们两者的关系是平等的,所以不属于继承关系。更好的的实现方式是:将形状和颜色分离,根据需要对形状和颜色进行组合,这就是桥接模式的思想。

新建接口类 IColor,仅包含一个获取颜色的方法:

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:22
 * @Description: 颜色接口
 */
public interface IColor {
​
    String getColor();
}

每种颜色都实现此接口:

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:23
 * @Description: 红色实现类
 */
public class RedColor implements IColor{
​
    @Override
    public String getColor() {
        return "红色";
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:23
 * @Description: 蓝色实现类
 */
public class BlueColor implements IColor{
​
    @Override
    public String getColor() {
        return "蓝色";
    }
}

在每个形状类中,桥接 IColor接口:

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:25
 * @Description: 圆形实现类
 */
public class Round implements Shape{
​
    private IColor iColor;
​
    void setColor(IColor iColor){
        this.iColor = iColor;
    }
​
    @Override
    public void draw() {
        System.out.println("绘制" + iColor.getColor() + "圆形");
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:27
 * @Description: 矩形实现类
 */
public class Rectangle implements Shape{

    private IColor iColor;

    void setColor(IColor iColor){
        this.iColor = iColor;
    }

    @Override
    public void draw() {
        System.out.println("绘制"+iColor.getColor()+"矩形");
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-08 9:28
 * @Description: 三角形实现类
 */
public class Triangle implements Shape{

    private IColor iColor;

    void setColor(IColor iColor){
        this.iColor = iColor;
    }

    @Override
    public void draw() {
        System.out.println("绘制 "+iColor.getColor()+"三角形");
    }
}

这时我们再来回顾一下官方定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。抽象部分指的是父类,对应本例中的形状类,实现部分指的是不同子类的区别之处。将子类的区别方式 —— 也就是本例中的颜色 —— 分离成接口,通过组合的方式桥接颜色和形状,这就是桥接模式,它主要用于 两个或多个同等级的接口



评论