目的
将抽象与其实现分离,以便两者可以独立变化。
说明
假设你有一个武器具有不同的魔法,你应该想混合不同的武器与不同的魔法。你会怎么做?为每个魔法创造每个武器的多个副本,还是只创建单独的魔法并根据需要为武器设置?桥接模式允许你做第二个。
简而言之
桥模式是关于优先组合而不是继承。实现细节从一个层次结构推送到另一个具有单独层次结构的对象。
维基百科说
桥接模式是软件工程中使用的设计模式,旨在“将抽象与其实现分离,以便两者可以独立变化”
源码示例
以上面的武器为例。
这里我们有Weapon层次结构
public interface Weapon { void wield(); void swing(); void unwield(); Enchantment getEnchantment(); }
public class Sword implements Weapon {
private final Enchantment enchantment;
public Sword(Enchantment enchantment) { this.enchantment = enchantment; }
@Override public void wield() { LOGGER.info("The sword is wielded."); enchantment.onActivate(); }
@Override public void swing() { LOGGER.info("The sword is swinged."); enchantment.apply(); }
@Override public void unwield() { LOGGER.info("The sword is unwielded."); enchantment.onDeactivate(); }
@Override public Enchantment getEnchantment() { return enchantment; } }
public class Hammer implements Weapon {
private final Enchantment enchantment;
public Hammer(Enchantment enchantment) { this.enchantment = enchantment; }
@Override public void wield() { LOGGER.info("The hammer is wielded."); enchantment.onActivate(); }
@Override public void swing() { LOGGER.info("The hammer is swinged."); enchantment.apply(); }
@Override public void unwield() { LOGGER.info("The hammer is unwielded."); enchantment.onDeactivate(); }
@Override public Enchantment getEnchantment() { return enchantment; } }
|
以及单独的魔法等级
public interface Enchantment { void onActivate(); void apply(); void onDeactivate(); }
public class FlyingEnchantment implements Enchantment {
@Override public void onActivate() { LOGGER.info("The item begins to glow faintly."); }
@Override public void apply() { LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand."); }
@Override public void onDeactivate() { LOGGER.info("The item's glow fades."); } }
public class SoulEatingEnchantment implements Enchantment {
@Override public void onActivate() { LOGGER.info("The item spreads bloodlust."); }
@Override public void apply() { LOGGER.info("The item eats the soul of enemies."); }
@Override public void onDeactivate() { LOGGER.info("Bloodlust slowly disappears."); } }
|
两种等级制度都在起作用
Sword enchantedSword = new Sword(new SoulEatingEnchantment()); enchantedSword.wield(); enchantedSword.swing(); enchantedSword.unwield(); // The sword is wielded. // The item spreads bloodlust. // The sword is swinged. // The item eats the soul of enemies. // The sword is unwielded. // Bloodlust slowly disappears.
Hammer hammer = new Hammer(new FlyingEnchantment()); hammer.wield(); hammer.swing(); hammer.unwield(); // The hammer is wielded. // The item begins to glow faintly. // The hammer is swinged. // The item flies and strikes the enemies finally returning to owner's hand. // The hammer is unwielded. // The item's glow fades.
|
适用场景
何时使用Bridge模式
- 您希望避免抽象与其实现之间的永久绑定。例如,必须在运行时选择或切换实现时可能就是这种情况。
- 抽象及其实现都应该通过子类化来扩展。在这种情况下,Bridge模式允许您组合不同的抽象和实现并独立扩展它们
- 抽象实现的变化应该对客户端没有影响; 也就是说,不必重新编译他们的代码。
- 你有很多类。这样的类层次结构表明需要将对象分成两部分。Rumbaugh使用术语“嵌套的泛化”来引用这样的类层次结构
- 你想在多个对象之间共享一个实现(可能使用引用计数),并从客户端隐藏这一事实。一个简单的例子是Coplien的String类,其中多个对象可以共享相同的字符串表示。