设计模式——桥接模式
三个例子说明白,什么是桥接模式、为什么用桥接模式、怎么用桥接模式、代码实现桥接模式
概述
举例子带入桥接模式
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(); } }
作者:coderymy
链接:https://juejin.cn/post/7023688166041190414