我正在开发一个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监听器。
这种模式有缺陷吗?我可以使用具有两个同时可见的父组件的相同组件或侦听器吗?
提前致谢。
答案 0 :(得分:8)
它有一个重大缺陷:它通过使每个组件在全球范围内可访问来促进缺乏封装。这可以非常快速地导致意大利面条代码,其中每个对象使用任何其他对象,而不是提供一个提供封装方法的简短依赖列表。
另一个问题是实现:同步是不必要的,因为Swing组件不是线程安全的,并且只能在事件派发线程中使用。因此,您应该只让EDT调用您的方法,这样就不需要进行同步。
最后,组件可能只有一个父组件。例如,如果相同的组件必须显示在两个不同的帧中,则需要此组件的两个实例。
答案 1 :(得分:0)
除了单例模式带来的耦合问题(=程序中的许多类依赖于您的工厂 - >如果您的工厂发生变化,系统的许多部分都会受到影响。),您的单件工厂应该工作在多线程环境中。
但要注意不要优化它。有一种称为双重检查锁定的技术,用于优化您的解决方案以获得更高程度的并发性,但它有非常微妙的问题。如果您有兴趣,请参阅此声明(并注明签名的人):http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
为了摆脱与工厂的耦合,我宁愿在一些顶级类中创建共享结构(表,监听器,框架),这些类也创建需要引用这些结构的对象。并将结构传递给它们的构造函数。但这只是一个建议,我不知道该计划的整体结构。