为了防止被“杀”了祭天,学点设计模式,并总结下还是有必要的。
一:理解
- 桥接模式可以将某个类从多个维度中分离出来。例如某人在某网站上写文章,某人和某网站就是两个维度。这两个维度相关,但可以拆分出来,已获得更灵活的组合。
- 桥接模式将类的继承关系转换成组合关系,使得系统更加灵活,同时减少类的个数。
二:例子
你是个富二代。
你掌控着庞大的家族企业。
和人交流是你的日常之一。
说是交流,其实就是吹牛X。
你的交流模式可以抽象出一个接口,接口中包含chuiNiuBi方法。
public interface Communication {
void chuiNiuBi();
}
说起吹牛X,你立马想到的是和美女在酒店吹牛X。
新建一个CommunicationWithBeautyAtHotel类。
public class CommunicationWithBeautyAtHotel implements Communication {
@Override
public void chuiNiuBi() {
System.out.println("在酒店和美女吹牛X!");
}
}
如果更换一个吹X的场合,或是更换一个吹X的人,就需要构建新的类,例如和美女在厕所吹牛X,和小弟在烧烤摊吹牛X等。
由于你的社交场合比较多(N个),朋友种类也比较多(M个),一共新建了N*M个类。
有一天,你觉得在厕所交流听着很变扭,想要把“在厕所”三个字改成“在洗手间”。
那么就需要修改M个和在厕所吹X相关的类。
如果忘记修改其中一个类,估计这个程序员又要被你杀了祭天了。
于是,你叫来了程序员小菜,让他帮你完成在洗手间优雅地吹牛X的任务。
小菜一看,这个问题可以分成两个维度,一个是和某人,第二个是在某地,即人物维度和地点维度。
他决定用桥接模式来连接这两个维度。
首先抽象人物维度。
这里只抽象和美女吹牛X以及和兄弟吹牛X类。
// 和美女吹牛X类
public class CommunicationWithBeauty implements Communication {
@Override
public void chuiNiuBi() {
System.out.println("和美女吹牛X!");
}
}
// 和兄弟吹牛X类
public class CommunicationWithBro implements Communication {
@Override
public void chuiNiuBi() {
System.out.println("和兄弟吹牛X!");
}
}
接着抽象地点维度,如在酒店交流CommunicationAtHotel,在酒店交流类其实只是在和某人交流类上多了一层。
那么,CommunicationAtHotel需要含有一个人物维度交流类的属性。
为了减少代码量,以及对地点维度交流类做限制。
小菜新建了一个抽象类:
@Data
public abstract class CommunicationAtPlace {
protected Communication communication;
public abstract void communicationAtPlace();
}
该类包含一个communication属性,以及communicationAtPlace方法。
接着又新建两个地点维度交流类,分别是在酒店交流和在厕所交流......
// 在酒店交流
public class CommunicationAtHotel extends CommunicationAtPlace {
@Override
public void communicationAtPlace() {
System.out.print("在酒店");
communication.chuiNiuBi();
}
}
// 在厕所交流
public class CommunicationAtWashroom extends CommunicationAtPlace {
@Override
public void communicationAtPlace() {
System.out.print("在厕所");
communication.chuiNiuBi();
}
}
可以看到,在输出地点之后,就会调用持有communication属性的chuiNiuBi方法,输出和某人在交流。
测试代码:
public class Client {
public static void main(String[] args) {
Communication communication = new CommunicationWithBeauty();
CommunicationAtPlace communicationAtHotel = new CommunicationAtHotel();
communicationAtHotel.setCommunication(communication);
communicationAtHotel.communicationAtPlace();
}
}
输入/输出:
在酒店和美女吹牛X!
当你需要把“在厕所”改成“在洗手间”时,只需修改CommunicationAtWashroom类即可。
你很开心,终于可以随心所欲地和任何人在任何地点吹牛X了。
于是,你露出了桥哥一般自信的微笑。
三:再理解
- 桥接模式支持对多个维度进行扩展,扩展其中一个维度时只需增加一个类。
- 使用桥接模式之后,类的数量从N*M个减少到N+M个。