设计模式之桥接模式
2022-04-30 本文已影响0人
发现未知的自己
1 定义
桥接模式将抽象部分与它的实现部分分离,使它们可以独立地变化。或者也可以定义为:一个类存在两个(或多个)独立变化的维度,我们可以通过组合的方式,让这两个(或多个)维度可以独立进行扩展。
2 类图
桥接模式.png3 伪代码实现
public abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
public class RefinedAbstraction extends Abstraction {
public void RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void operation() {
implementor.operationImpl();
}
}
public interface Implementor {
void operationImpl();
}
public class ConcreteImplementorA {
public void operationImpl() {
}
}
public class ConcreteImplementorB {
public void operationImpl() {
}
}
4 使用场景
假设有两个手机品牌M和N,两个品牌都有游戏和通讯录,从面向对象的角度来设计,如果采用继承的方式,我们会做如下设计:
c7661ca54385912394a7528aafe366fd.png(引自大话设计模式)
或
3b91dbcc141f666276bd29fa1d555de9.png(引自大话设计模式)
上面两种方式虽然采用了面向对象的设计方式,遵循了对修改关闭对扩展开放的设计原则,但是仔细想想,会出现什么问题?假设我们还有手机品牌H,I...,各类手机还有音乐软件、阅读软件等等其他软件,手机品牌和软件一组合,我们要编写的类就会出现指数级增长,这会导致系统越来越庞大,难以管理。
在这种情况下,我们就可以使用桥接模式,将继承改成组合的方式,增加一个手机品牌,我们只需增加一个品牌子类即可,增加一个软件,我们也只需增加一个类就行,新的手机品牌和新的软件功能只要组合起来就行了。
4.1 java代码
public interface IHandsetSoft {
void run();
}
public class HandsetGame implements IHandsetSoft {
@Override
public void run() {
System.out.println("运行手机游戏");
}
}
public class HandsetAddressList implements IHandsetSoft {
@Override
public void run() {
System.out.println("运行手机通讯录");
}
}
public abstract class HandsetBrand {
protected IHandsetSoft handsetSoft;
public HandsetBrand(IHandsetSoft handsetSoft) {
this.handsetSoft = handsetSoft;
}
public abstract void run();
}
public class HandsetBrandM extends HandsetBrand {
public HandsetBrandM(IHandsetSoft handsetSoft) {
super(handsetSoft);
}
@Override
public void run() {
System.out.println("手机品牌M");
handsetSoft.run();
}
}
public class HandsetBrandN extends HandsetBrand {
public HandsetBrandN(IHandsetSoft handsetSoft) {
super(handsetSoft);
}
@Override
public void run() {
System.out.println("手机品牌N");
handsetSoft.run();
}
}
public class Client {
public static void main(String[] args) {
// 手机游戏
IHandsetSoft handsetGame = new HandsetGame();
// 手机通讯录
IHandsetSoft handsetAddressList = new HandsetAddressList();
// 在手机品牌M上运行手机游戏
HandsetBrand handsetBrandM = new HandsetBrandM(handsetGame);
handsetBrandM.run();
// 在手机品牌M上运行手机通讯录
handsetBrandM = new HandsetBrandM(handsetAddressList);
handsetBrandM.run();
// 在手机品牌N上运行手机游戏
HandsetBrand handsetBrandN = new HandsetBrandN(handsetGame);
handsetBrandN.run();
// 在手机品牌N上运行手机通讯录
handsetBrandN = new HandsetBrandN(handsetGame);
handsetBrandN.run();
}
}
采用继承的方式,是一种紧耦合的方式,可以做扩展,但是比较困难,采用组合的方式是一种松耦合的方式,可以进行轻松的扩展。继承是is-a的关系,如果是is-a的关系,适合使用继承,组合是has-a的关系,如果是has-a的关系,适合使用组合。比如上面是手机上有手机游戏和手机通讯录,所以用组合更合适。
再比如红色长方形,绿色长方形,红色圆形,绿色圆形,可以理解为长方形或者原型具有红色或者绿色的属性,可以使用组合的方式。类图如下:
(引自https://www.runoob.com/design-pattern/bridge-pattern.html)