日前,与不知名网友聊天时候谈到桥接模式,不懂,亦好面,遂研究之!
在桥接模式之前,还想唠点闲嗑,那就先谈谈设计模式把。
我特喜欢笑傲江湖,喜欢独孤九剑,在学习设计模式以后,我理解了,悟了,这他妈就是代码中的独孤九剑啊。(我喜欢央版的笑傲!!)
为什么这么说,独孤九剑只有九剑,却包含了万千变化(僻邪剑谱离我远点!),而设计模式亦然,但独孤有九剑,而我,只懂三四种设计模式。
好了,嗑唠完了,开始进正题。
什么是桥接模式?
桥接模式:将多个策略模式糅到一起,相互独立,却又关联。
策略模式可以参考我之前写的策略模式的博客(我懒得去找链接了)。
策略模式是一种方法的不同实现,就像茴香豆的茴字的很多种写法。
我们以茴香豆为例来写桥接模式:
茴香豆的写法呢,有很多种,我们只用两种,简体的和繁体的(其他的我也不会啊),写茴香豆的人呢,也是两种,孔乙己,鲁迅。
这时候呢,路人甲跳出来了,“孔乙己,你会写简体的茴字嘛?鲁迅,你会写繁体的茴字嘛?”‘
孔乙己这能服?
这时候我们的代码是什么样的呢?
如下:
/**
* @author hanyuhuai
* @version 1.0
* @description: 孔乙己
* @date 2022/5/31 15:03
*/
public class KYJ {
void writeHuiXiangDou(){
System.out.println("简体字的茴香豆");
}
}
/**
* @author hanyuhuai
* @version 1.0
* @description: 鲁迅
* @date 2022/5/31 15:04
*/
public class LX {
void writeHuiXiangDou(){
System.out.println("繁体字的茴香豆");
}
}
此时呢,路人甲又说了,那孔乙己会写繁体的茴字嘛?鲁迅会写简体的茴字嘛?
作为主人公的孔乙己和鲁迅没啥意见,可tm写代码的我有意见啊,总不能再写俩方法吧,如果路人甲再让主人公写其他字体的茴字,难道我都要再开发一遍?如果这时候出来一个周树人,说他也会写,难道我还得再写一个类?在类上面再写很多个茴字?
于是对代码进行修改
从两个维度考虑,一,增加人员,二,增加茴香豆的写法;
同时,增加的人员也要写茴香豆
代码如下:
/**
* @author hanyuhuai
* @version 1.0
* @description: 写字的人
* @date 2022/5/31 15:12
*/
public abstract class Personnel {
public FontWriting fontWriting;
public Personnel(FontWriting fontWriting) {
this.fontWriting = fontWriting;
}
public abstract void write();
}
/**
* @author hanyuhuai
* @version 1.0
* @description: 字体写法
* @date 2022/5/31 15:13
*/
public interface FontWriting {
void write();
}
import com.flowable.demo.bridging.FontWriting;
/**
* @author hanyuhuai
* @version 1.0
* @description: 具体的繁体字写法实现
* @date 2022/5/31 15:15
*/
public class FanTi implements FontWriting {
@Override
public void write() {
System.out.println("写繁体字的茴香豆");
}
}
/**
* @author hanyuhuai
* @version 1.0
* @description:具体的简体字写法实现
* @date 2022/5/31 15:15
*/
public class JianTi implements FontWriting {
@Override
public void write() {
System.out.println("写简体字的茴香豆");
}
}
/**
* @author hanyuhuai
* @version 1.0
* @description: 写茴字的孔乙己
* @date 2022/5/31 15:19
*/
public class KYJ extends Personnel {
public KYJ(FontWriting fontWriting) {
super(fontWriting);
}
@Override
public void write() {
System.out.print("我:孔乙己");
fontWriting.write();
}
}
/**
* @author hanyuhuai
* @version 1.0
* @description:写茴字的鲁迅
* @date 2022/5/31 15:19
*/
public class LX extends Personnel {
public LX(FontWriting fontWriting) {
super(fontWriting);
}
@Override
public void write() {
System.out.print("我:鲁迅");
fontWriting.write();
}
}
/**
* @author hanyuhuai
* @version 1.0
* @description:写茴字的周树人
* @date 2022/5/31 15:19
*/
public class ZSR extends Personnel {
public ZSR(FontWriting fontWriting) {
super(fontWriting);
}
@Override
public void write() {
System.out.print("我:周树人");
fontWriting.write();
}
}
/**
* 测试代码
* @author hanyuhuai
* @date 2022/5/31 15:31
* @return void
*/
public static void main(String[] args) {
LX lx = new LX(new JianTi());
lx.write();
ZSR zsr = new ZSR(new FanTi());
zsr.write();
KYJ kyj = new KYJ(new JianTi());
kyj.write();
}
结果如下:
上述代码就是桥接模式的实现。
关键点呢,是在写字的人那块,也就是Personnel抽象类,这个类定义了字体写法的引用,并在创建时候进行赋值,然后在具体写字的人写字的时候调用字体写法的简体字和繁体字写法的方法。(谁作为引用方,谁就是那个抽象类,谁是被引用方,谁就是接口)
有些人就说了:你这一个类一个方法,还不如我直接写几个类来的直接,而且还麻烦。
那咱就得说了,这样的好处是是什么?
新增字体,那我们只需要修改/新增一个调用就行,这种写法,调用,甚至可以放在配置文件,灵活取用,新增人员也是同理,它的扩张性相对最原生的枚举写法,要灵活,有效的多。
好了,今天的独孤九剑就学到这!