设计模式——桥接模式

458 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

三个例子说明白,什么是桥接模式、为什么用桥接模式、怎么用桥接模式、代码实现桥接模式

概述

举例子带入桥接模式

1、一个士兵,一开始只分兵种,也就是步兵还是骑兵。等到了有一定功勋之后开始分配士兵的等级A等、B等、C等

2、咖啡,一开始售卖只需要关注是大杯还是中杯。售卖一段时间发现有人喜欢加糖有人喜欢加牛奶,所以又增加了属性加糖、加牛奶、什么都不加

3、绘画,一开始只关注我是画一个圆还是画一个五角星。但是老师说要活灵活现,所以增加了色彩红色、黄色、蓝色

什么是桥接模式

结构型模式,把抽象化与实现化解耦,通过桥接两者来完成二者的解藕

为什么要使用桥接模式

看下大佬的例子(士兵)

这里士兵有两个属性-等级和兵种。那么如果我再加一个兵种“特种兵”,是不是就需要增加三个实现,即A等特种兵、B等特种兵、C等特种兵?

(咖啡),如果我再加上小杯,是不是又增加了小杯什么都不加,小杯加糖,小杯加牛奶

(绘画),如果加上了三角形,是不是加上了红色三角形、黄色三角形、蓝色三角形

上述看起来是不是太过冗余了

如果这些属性相互解藕,也就是兵种是单独的属性、士兵等级是一个属性,只需要在实现对象的时候进行排列组合而不是生成具体的实现类 。

什么时候使用桥接模式

多个属性标识同一个抽象类,之间可以相互排列组合生成具体的实现类

实现

逻辑实现

1、 一个具体需要的抽象类(abstract class),比如士兵、咖啡、绘画结果;及其构造方法,和业务需要的逻辑方法

2、 原有的抽象类实现对象(工兵、大杯咖啡、一个圆形绘画),实现抽象类并实现其具体的业务逻辑

3、 新增的接口,例如(士兵职级、加糖、色彩),及其接口需要的方法约束

4、 接口的实现类,例如(A级,加糖,红色),及其具体的业务实现

5、 调用时

  • 实现新增的实现类
  • 创建抽象类的具体实现对象
  • 调用具体实现方法

代码实现(士兵的等级和工种)

1.创建士兵抽象类(抽象类的属性包括等级和名称)

**
 * @ClassName Soldier
 * @Desc 抽象士兵类(最主要的)
 * 1。 抽象了一个士兵需要的特性
 * 2。 将士兵的性质(步兵、骑兵)和士兵的等级(A、B、C)相互桥接起来
 * @Author YangMingYu
 * @Date 2021/10/27 10:50 上午
 * @Version 1.0
 **/
public abstract class Soldier {
    
    private String name;
    Rank rank;

    public Soldier(Rank rank, String name) {
        this.rank = rank;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void type();
}
  1. 创建士兵的实现类(步兵、骑兵、弓箭手)
/**
 * @ClassName Infantry
 * @Desc 步兵
 * @Author YangMingYu
 * @Date 2021/10/27 10:53 上午
 * @Version 1.0
 **/
public class Infantry extends Soldier {
    public Infantry(Rank rank, String name) {
        super(rank, name);
    }

    @Override
    public void type() {
        //表达兵种性质
        System.out.print("我是步兵" + this.getName() + ",");
        //表达兵种等级
        rank.rankByAchieve();
    }
}

/**
 * @ClassName Cavalry
 * @Desc 骑兵
 * @Author YangMingYu
 * @Date 2021/10/27 10:56 上午
 * @Version 1.0
 **/
public class Cavalry extends Soldier {
    public Cavalry(Rank rank, String name) {
        super(rank, name);
    }
    @Override
    public void type() {
        //表达兵种性质
        System.out.print("我是步兵" + this.getName() + ",");
        //表达兵种等级
        rank.rankByAchieve();
    }
}
/**
 * @ClassName Bowman
 * @Desc 弓箭手
 * @Author YangMingYu
 * @Date 2021/10/27 10:56 上午
 * @Version 1.0
 **/
public class Bowman extends Soldier {
    public Bowman(Rank rank, String name) {
        super(rank, name);
    }

    @Override
    public void type() {
        //表达兵种性质
        System.out.print("我是弓箭手" + this.getName() + ",");
        //表达兵种等级
        rank.rankByAchieve();
    }
}

  1. 创建等级的接口
/**
 * @ClassName Rank
 * @Desc 等级接口
 * @Author YangMingYu
 * @Date 2021/10/27 10:51 上午
 * @Version 1.0
 **/
public interface Rank {
    void rankByAchieve(); // 根据成就来划分等级
}
  1. 创建等级的实现类
/**
 * @ClassName RankForA
 * @Desc A等
 * @Author YangMingYu
 * @Date 2021/10/27 10:52 上午
 * @Version 1.0
 **/
public class RankForA implements Rank {


    @Override
    public void rankByAchieve() {
        System.out.println("等级A...");
    }
}
/**
 * @ClassName RankForA
 * @Desc B等
 * @Author YangMingYu
 * @Date 2021/10/27 10:52 上午
 * @Version 1.0
 **/
public class RankForB implements Rank {


    @Override
    public void rankByAchieve() {
        System.out.println("等级B...");
    }
}
/**
 * @ClassName RankForA
 * @Desc C等
 * @Author YangMingYu
 * @Date 2021/10/27 10:52 上午
 * @Version 1.0
 **/
public class RankForC implements Rank {


    @Override
    public void rankByAchieve() {
        System.out.println("等级C...");
    }
}

  1. 生成士兵对象并调用方法描述自己
/**
 * @ClassName BridgingDemo
 * @Desc 桥接对象的使用
 * 1。 桥接的属性实现类对象(新增的属性)
 * 2。 桥接另一个属性的实现对象(原)
 * 3。 调用原有属性生成的实现对象的对应方法
 * @Author YangMingYu
 * @Date 2021/10/27 10:57 上午
 * @Version 1.0
 **/
public class BridgingDemo {

    public static void main(String[] args) {
        Rank rankA = new RankForA();
        Infantry infantry = new Infantry(rankA, "xiaoMing"); // 步兵
        infantry.type();
        Cavalry cavalry = new Cavalry(rankA, "xiaoWu"); // 骑兵
        cavalry.type();

        Rank rankB = new RankForB();
        Infantry infantry2 = new Infantry(rankB, "xiaoLi"); // 步兵
        infantry2.type();
    }
}

学习自:

  1. Starry-大佬以及大话设计模式
  2. 菜鸟教程