小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
三个例子说明白,什么是桥接模式、为什么用桥接模式、怎么用桥接模式、代码实现桥接模式
概述
举例子带入桥接模式
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();
}
- 创建士兵的实现类(步兵、骑兵、弓箭手)
/**
* @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();
}
}
- 创建等级的接口
/**
* @ClassName Rank
* @Desc 等级接口
* @Author YangMingYu
* @Date 2021/10/27 10:51 上午
* @Version 1.0
**/
public interface Rank {
void rankByAchieve(); // 根据成就来划分等级
}
- 创建等级的实现类
/**
* @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...");
}
}
- 生成士兵对象并调用方法描述自己
/**
* @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();
}
}
学习自: