单例 Swing 组件
我正在开发一个 swing 应用程序,其中有一个 Factory 类,它提供了保持 Singleton 的组件。就像:
public final class ComponentFactory {
private static LibraryFrame libraryFrame;
private static LibraryTableScrollPane libraryTableScrollPane;
public static synchronized LibraryFrame getLibraryFrame() {
if (libraryFrame == null) {
libraryFrame = new LibraryFrame();
}
return libraryFrame;
}
public static synchronized LibraryTableScrollPane getLibraryTableScrollPane() {
if(libraryTableScrollPane == null) {
libraryTableScrollPane = new LibraryTableScrollPane(getLibraryTable());
}
return libraryTableScrollPane;
}
}
我将此组件用作:
add(ComponentFactory.getLibraryTableScrollPane())
此外,我还创建了一个 ListenerFactory 类,它提供了 Swing/AWT 的各种侦听器。
这个模式有什么缺陷吗?我可以将同一个组件或侦听器与两个同时可见的父组件一起使用吗?
提前致谢。
I am developing a swing app, where I have a Factory class which provide Component keeping Singleton in mind. Like:
public final class ComponentFactory {
private static LibraryFrame libraryFrame;
private static LibraryTableScrollPane libraryTableScrollPane;
public static synchronized LibraryFrame getLibraryFrame() {
if (libraryFrame == null) {
libraryFrame = new LibraryFrame();
}
return libraryFrame;
}
public static synchronized LibraryTableScrollPane getLibraryTableScrollPane() {
if(libraryTableScrollPane == null) {
libraryTableScrollPane = new LibraryTableScrollPane(getLibraryTable());
}
return libraryTableScrollPane;
}
}
I am using this component as:
add(ComponentFactory.getLibraryTableScrollPane())
Also I make a ListenerFactory class which provides various Listeners of Swing/AWT.
Is this pattern has any flaws? Can I use a same component or listener with two concurrently visible parent component?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它有一个主要缺陷:它使每个组件都可以全局访问,从而导致缺乏封装。这可能很快导致意大利面条式代码,其中每个对象都使用任何其他对象,而不是提供封装方法的简短依赖项列表。
另一个问题与实现有关:同步是不必要的,因为 Swing 组件不是线程安全的,并且只能在事件分派线程中使用。因此,您应该只让 EDT 调用您的方法,这使得同步变得不必要。
最后,一个组件只能有一个父组件。例如,如果相同的组件必须显示在两个不同的框架中,则您将需要该组件的两个实例。
It has a major flaw: it promotes a lack of encapsulation by making every component globally accessible. This can lead very quickly to spaghetti code where every object uses any other object, instead of having a short list of dependencies providing encapsulated methods.
Another problem is with the implementation: the synchronization is unnecessary, since Swing components are not thread-safe, and may only be used from the event dispatch thread. You should thus only have the EDT calling your methods, which makes synchronization unnecessary.
Finally, a component may only have one parent component. If the same compoentnmust be displayed in two different frames, for example, you'll need two instances of this component.
除了单例模式带来的耦合问题(=程序中的许多类都依赖于你的工厂->如果你的工厂发生变化,系统的许多部分都会受到影响。),你的单例工厂应该在多模式下工作- 线程上下文。
但要注意不要优化它。有一种称为双重检查锁定的技术,用于优化您的解决方案以获得更高程度的并发性,但它有非常微妙的问题。如果您有兴趣,请参阅此声明(并记下签署该声明的人员):http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
为了摆脱与工厂的耦合,我宁愿创建共享结构(表、侦听器、框架)在一些顶级类中,这些类还创建需要引用这些结构的对象并将这些结构传递到其构造函数中。但这只是一个建议,我不知道程序的整体结构。
Apart from the coupling problems that come with the singleton pattern (= many classes in your program have a dependency on your factory -> If your factory changes, many parts of your system are affected.), your singleton factory should work in a multi-threaded context.
But be careful not to optimize it. There is a technique called double-checked locking that was used to optimize your solution to get a higher degree of concurrency, but it has very subtle problems. If you are interested, see this declaration (and note people who signed it): http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
To get rid of the coupling to your factory, I would rather create the shared structures (tables, listeners, frames) in some top-level class(es) that also create(s) the objects that need references to these structures and pass the structures into their constructors. But that is just an advice, I do not know the overall structure of the program.