对我来说,Bridge 并不是 GOF 圣经中最重要的 DP,因为它主要是 Strategy 的衍生品。作为其他一些没有那么好老化的模式(工厂方法?),它意味着与其他模式相比,抽象类拥有更多的继承行为,因此不太普遍适用。
主要是战略在做大工作,但战略的一个主要问题是战略通常需要了解其背景。
在某些语言中,这会导致策略被声明为上下文的朋友,或者在 Java 中将策略定义为内部类。
这意味着上下文通常以了解各种具体策略的存在而告终。您可以通过使用 setStrategy() 函数来避免这种情况,但由于效率原因,从具体策略到上下文的反向依赖通常会存在(您希望直接操作上下文的数据结构)。
Bridge 解决了这个问题,因为 Strategy 的上下文现在是抽象的,但仍然是一个先验类,因为它至少有 Strategy 的代码。它通常应该定义一个足以让具体策略使用的访问 API,可能带有漏洞,即抽象方法。您将 AbstractContext 的出现放在 AbstractStragey 上的操作签名中,您很好。
因此,在我看来,Bridge 通过使上下文足够具体以使策略起作用来完成策略,但仍然足够抽象以使其可以通过 w.r.t 正交细化。具体策略(在实现具体策略实际使用的上下文的抽象 API 时具有反馈效果)。
查看桥的更简单的方法是说 AbstractStrategy 操作应该始终将抽象作为参数,而不是真正了解它们的上下文。
更准确地回答 OP 问题:
这句话是什么意思?实现是否位于单独的 jar 中?
是的,确实,通常您可以在包“base”中定义 Abstraction 和 Implementor(它们可以是接口)。具体实施者可以各自驻留在包“implXX”中。具体上下文可以驻留在单独的包“contXX”中。依赖图中没有循环,每个人都依赖于基础,可以独立定义新的“contXX”和“implXX”(它们之间根本没有依赖关系),因此 OP 中的粗体声明。
独立变化语句的含义是什么?
想想eclipse中的一个编辑器插件;它必须处理按钮和点击上的操作(如策略),但策略需要执行的实际操作是对编辑器状态本身进行操作(例如“突出显示文本”)。您以抽象的方式定义编辑器所拥有的内容,包括它具有用于 clics 和按键的处理程序以及突出显示和导航功能的事实,即使这些都可以被具体的编辑器覆盖(flash 而不是突出显示)。这是一座桥梁,您可以独立定义新的编辑器和新的处理程序。
通过一些依赖注入(例如 Google guice)或一些手动工厂代码或组件方向来从外部干净地 setStrategy,您可以获得应用程序各个部分的非常低的耦合。
考虑提供的 journaldev 文章,详细说明答案。
老实说,我认为这不是 DP 的最佳应用,因为 Color 实现似乎不太关心它们的上下文。您应该在这里使用装饰器,因为颜色是形状的独立关注点。
查看这些幻灯片,了解使用装饰器的解决方案(部分是法语,抱歉)。
https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-9.pdf(幻灯片 16-18)基于此处介绍的示例:
https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-4.pdf
幻灯片 10 到 15。
在该示例中,如果“updateInertie”是 Forme 的成员,我们将需要 Bridge,这听起来并不荒谬。 Bridge 再次更多地作为其他模式的组合出现。