桥接模式 - Java 编译的好处?

发布于 2024-12-19 18:10:42 字数 702 浏览 2 评论 0原文

《设计模式 - 可重用面向对象软件的元素》一书中说:

在只有一个实现(一对一)的情况下,创建一个 抽象实现类不是必需的。这是一种退化情况 桥型图案;之间存在一对一的关系 抽象和实现。尽管如此,这种分离仍然存在 当类的实现的更改不得影响时很有用 其现有客户——也就是说,他们不应该是 重新编译,刚刚重新链接。

我对编译时间的好处表示怀疑,因为我无法想象 Java 中实现的更改会导致重新编译其超类(在本例中为抽象类)的情况。

例如,如果我们有 X 扩展 Y 并且客户端执行以下操作:

Y y = new X();  

X 中的更改并不意味着 Y 的重新编译(当然,如果我们不想更改 X 的方法签名),

这与使用时完全相同桥接模式:

YAbstraction yabstraction = new YRefinedAbstraction(new XImplementor());

XImplementor 的更改并不意味着 YAbstraction 的重新编译。

因此,据我所知,这种好处在 Java 中不会发生,并且对于一对一 =>不需要桥接模式。

也许子类的更改会迫使超类用其他语言重新编译?像 SmallTalk 和 C++ 一样?

你有什么意见?

It is said in Design Patterns - Elements of Reusable Object-Oriented Software book :

In situations where there's only one implementation (one-to-one) ,creating an
abstract implementor class isn't necessary.This is a degenerate case
of the bridge pattern; there's a one-to-one relationship between
Abstraction and Implementor.Nevertheless,this seperation is still
useful when a change in the implementation of a class must not affect
its existing clients- that is they shouldn't have to be
recompiled,just relinked.

I doubt about the benefit of compile time because I can't imagine a case in Java where a change in implementation makes recompile its superclass (abstract in this case).

For example, if we have X extends Y and a client do :

Y y = new X();  

A change in X does not mean a recompilation of Y (of course if we don't want to change the method signatures of X)

It is exactly the same thing when using Bridge Pattern :

YAbstraction yabstraction = new YRefinedAbstraction(new XImplementor());

A change in XImplementor does not mean a recompilation of YAbstraction.

So, according to me, this benefit does not take place in Java and for a one-to-one => no Bridge Pattern needed.

Perhaps a change in a subclass force superclass to be recompiled in other languages ? like SmallTalk and C++ ?

What are your opinions ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你与昨日 2024-12-26 18:10:42

在桥接模式中,您有两个类层次结构:一种用于抽象(例如具有 DialogWindow 和 IconWindow 等派生类的 Window),一种用于实现者(例如具有 XWindowImpl 和 PMWindowImpl 等派生类的 WindowImpl)。实现者的接口应该对抽象的客户端隐藏。通常,实现者提供低级原语,而抽象根据这些原语构建更高级别的操作,因此在分层良好的系统中,客户端应该不需要看到实现者提供的低级接口。如果有一天,WindowImpl 提供的接口不够通用,无法容纳新的 XYZWindowImpl,您仍然可以自由地更改它,因为 WindowImpl 永远不应该由您的客户端直接使用,而只能由 Window 及其子类使用。因此,WindowImpl接口的改变可能需要对Window进行修改,但不会传播到客户端。此外,人们经常将实现者隐藏在用于配置桥的抽象工厂后面。

您所描述的桥接模式的优点取决于对抽象的客户端隐藏实现者的接口。在 C++ 中,您可以通过简单地不提供头文件来轻松隐藏 Implementor 的接口。在 Java 中,您可以将 Implementor 设为具有包私有成员的抽象类。

在 C++ 中,抽象的客户端不需要重新编译,只需重新链接。在 Java 中,您不需要链接,而是进行类加载,因此您需要做的就是使用新设置和新的 jar 文件重新加载应用程序。

例如,想象一下这样一种情况:抽象工厂使用命令行选项或环境变量来使用正确类型的 ConcreteImplementor 配置桥。在这种情况下,您只需使用新的命令行/环境设置和包含新 ConcreteImplementor 的新 jar 文件重新加载应用程序。您无需重新编译客户端代码即可完成此操作。

因此,为您的问题提供直接答案:在 Java 中,桥接模式也确实具有问题中描述的优点。如果您考虑到从未发生过重新链接的事实,那么可能会更大。

In the bridge pattern you have two class hierarchies: one for the Abstraction (e.g. Window with derived classes like DialogWindow and IconWindow) and one for the Implementor (e.g. WindowImpl with derived classes like XWindowImpl and PMWindowImpl). Implementor's interface should be hidden from the clients of the Abstraction. Normally, the Implementor provides low-level primitives and the Abstraction builds higher-level operations in terms of those primitives, thus in a well-layered system clients should have no need to see the low-level interface offered by the Implementor. If one day, it turns out that the interface offered by WindowImpl isn't general enough to accomodate new XYZWindowImpl, you retain the freedom to change it since WindowImpl should never be used directly by your clients but only by Window and its subclasses. Thus, the change in the interface of WindowImpl may require modifications to Window, but will not propagate to the clients. Also, one often hides the Implementor behind an Abstract Factory which is used to configure the bridge.

The advantage of the Bridge pattern you described depends on hiding of Implementor's interface from the clients of the Abstraction. In C++ you can easily hide Implementor's interface by simply not providing the header file. In Java you can make the Implementor an abstract class with package private members.

In C++ clients of the Abstraction will not need to be recompiled, only relinked. In Java, instead of linking you have class loading and thus all you need to do is reload the application with new settings and a new jar file.

Imagine for example a situation when a command line option or an environment variable is used by an Abstract Factory to configure the bridge with the right kind of ConcreteImplementor. In such case you simply need to reload the application with new command line/environment settings and a new jar file containing the new ConcreteImplementor. You can do this without recompiling client code.

Thus to provide direct answer to your question: also in Java the Bridge pattern does have the advantage described in the question. Possibly to even greater extent if you count the fact that no relinking ever takes place.

拥抱我好吗 2024-12-26 18:10:42

Java 没有像 C/C++ 那样的“链接”。但是,我认为这个概念仍然适用:如果实现类位于与抽象不同的单独库(.jar 文件)中,那么您不必重新打包包含抽象的 .jar 文件。这可以简化复杂系统的维护。

Java doesn't have "linking" in the same way that C/C++ does. However, I think that the concept still applies: if the implementation class is in a separate library (.jar file) from the abstraction, then you don't have to repackage the .jar file containing the abstraction. This can simplify maintenance of a complex system.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文