桥接模式
-
意图
-
将抽象与其实现相分离,使得两者可以独立变化。
-
-
解释
案例:考虑武器有不同的特效,你想让不同的武器可以有不同的特效,你应该怎么做? 为每个武器创建不同的副本使得有不同的特效,还是你只单独创建单独的属性,在武器需要该属性时装配上即可。桥接模式可以让你有第二种选择。
简单说: 桥接模式更喜欢组合模式而不是继承模式,这种模式使得实现的细节从一个对象的层次结构到另一个对象的层级结构。
-
样例
//特效属性 public interface Enchantment { void onActive(); void apply(); void onDeactive(); }
//飞行特效 public class FlyingEnchantment implements Enchantment{ @Override public void onActive() { System.out.println("The item begins to glow faintly"); } @Override public void apply() { System.out.println("The item flies strikes the enemies finally returning to owner's hand"); } @Override public void onDeactive() { System.out.println("The items's glow fades"); } }
//噬魂特效 public class SoulEatingEnchantment implements Enchantment{ @Override public void onActive() { System.out.println("The item spreads bloodlust"); } @Override public void apply() { System.out.println("The item eats the soul of enemies"); } @Override public void onDeactive() { System.out.println("The item stops spreading bloodlust"); } }
//武器 public interface Weapon { void wield(); void swing(); void unwield(); Enchantment getEnchantment(); }
//锤子 public class Hammer implements Weapon{ private final Enchantment enchantment; public Hammer(Enchantment enchantment) { this.enchantment = enchantment; } @Override public void wield() { System.out.println("The hammer is wielded"); enchantment.onActive(); } @Override public void swing() { System.out.println("The hammer is swinged"); enchantment.apply(); } @Override public void unwield() { System.out.println("The hammer is unwielded"); } @Override public Enchantment getEnchantment() { return enchantment; } }
//剑 public class Sword implements Weapon{ private final Enchantment enchantment; public Sword(Enchantment enchantment) { this.enchantment = enchantment; } @Override public void wield() { System.out.println("This sword is wielded"); enchantment.onActive(); } @Override public void swing() { System.out.println("The sword is swinged"); enchantment.apply(); } @Override public void unwield() { System.out.println("The sword is unwielded"); enchantment.onDeactive(); } @Override public Enchantment getEnchantment() { return enchantment; } }
public class Main { public static void main(String[] args) { System.out.println("The knight receives an enchanted sword"); var enchantedSword = new Sword(new SoulEatingEnchantment()); enchantedSword.wield(); enchantedSword.swing(); enchantedSword.unwield(); System.out.println("The valkyries receives an enchanted hammer"); var enchantedHammer = new Hammer(new FlyingEnchantment()); enchantedHammer.wield(); enchantedHammer.swing(); enchantedHammer.unwield(); } }
-
你希望将对象的抽象与其实现相分离。例如,当在运行时,实现需要改变。
-
抽象与其实现应该通过子类进行扩展。在这个例子中,桥接模式让不同的抽象和实现相组合,并独立的扩展它们。
-
抽象的实现不应该对客户端造成影响。也就是说,不应该重新编译它们的代码。
-
你有大量的类,这样的类结构表明需要将对象分为两部分,使用“嵌套概括”来指代这样的类层次结构。
-
你希望在多个对象中共享一个实现,并对客户端隐藏这一事实。一个简单的例子是Coplien的String类,其中多个对象可以共享相同的字符串表示。