桥梁模式(Bridge DP)的定义是:解耦抽象与实现,让两者能够分别变化。
桥梁模式的名字可能有一点费解,为什么是桥而不是别的呢?我个人理解就是像桥一样连接抽象和实现,虽然说感觉哪里怪怪的,不过也找不到更好的说法了。
至于其定义,如果了解策略模式的话应该不会陌生,因为策略模式是解耦实现,运行时切换方法族;桥梁模式就像进阶的策略模式,不仅实现策略可以切换,连实现的载体也能抽象出来然后切换。
举一个例子,《黑暗之魂》中很多武器都是Boss用玩家也能用的,那么这里就有两个抽象层面:一个是主体的抽象,可能是主角或者Boss;另一个是实现的抽象,即武器的各种攻击方式。比起每个组合创建一个对象,用乘法明显减少最终对象的数量。
代码示例:
这个例子中,抽象对应魔法武器,抽象魔法武器的实现(动作)。
抽象类魔法武器,组合一个实现的抽象,规定三个动作:
/**
*
* MagicWeapon
*
*/
public abstract class MagicWeapon {
protected MagicWeaponImpl imp;
public MagicWeapon(MagicWeaponImpl imp) {
this.imp = imp;
}
public abstract void wield();
public abstract void swing();
public abstract void unwield();
public MagicWeaponImpl getImp() {
return imp;
}
}
抽象类,魔法武器实现,包含三个动作的实现方法:
/**
*
* MagicWeaponImpl
*
*/
public abstract class MagicWeaponImpl {
public abstract void wieldImp();
public abstract void swingImp();
public abstract void unwieldImp();
}
到这里其实已经比较清楚了,两个类都是抽象类,因此会派生出一些子类,魔法武器子类与魔法武器实现子类,互相之间是解耦的,可以任意搭配,也就是桥梁模式。
为了简单起见,这里只举出一个例子:
本体:
/**
*
* BlindingMagicWeapon
*
*/
public class BlindingMagicWeapon extends MagicWeapon {
public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
super(imp);
}
@Override
public BlindingMagicWeaponImpl getImp() {
return (BlindingMagicWeaponImpl) imp;
}
@Override
public void wield() {
getImp().wieldImp();
}
@Override
public void swing() {
getImp().swingImp();
}
@Override
public void unwield() {
getImp().unwieldImp();
}
public void blind() {
getImp().blindImp();
}
}
实现,这里继续做了一层抽象,增加一个方法:
/**
*
* BlindingMagicWeaponImpl
*
*/
public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl {
public abstract void blindImp();
}
然后真正的实现类:
/**
*
* Excalibur
*
*/
public class Excalibur extends BlindingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class);
@Override
public void wieldImp() {
LOGGER.info("wielding Excalibur");
}
@Override
public void swingImp() {
LOGGER.info("swinging Excalibur");
}
@Override
public void unwieldImp() {
LOGGER.info("unwielding Excalibur");
}
@Override
public void blindImp() {
LOGGER.info("bright light streams from Excalibur blinding the enemy");
}
}
没错,用咖喱棒闪瞎敌人狗眼!