Singleton Swing组件

时间:2012-02-19 09:58:34

标签: java swing concurrency singleton event-dispatching

我正在开发一个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监听器。

这种模式有缺陷吗?我可以使用具有两个同时可见的父组件的相同组件或侦听器吗?

提前致谢。

2 个答案:

答案 0 :(得分:8)

它有一个重大缺陷:它通过使每个组件在全球范围内可访问来促进缺乏封装。这可以非常快速地导致意大利面条代码,其中每个对象使用任何其他对象,而不是提供一个提供封装方法的简短依赖列表。

另一个问题是实现:同步是不必要的,因为Swing组件不是线程安全的,并且只能在事件派发线程中使用。因此,您应该只让EDT调用您的方法,这样就不需要进行同步。

最后,组件可能只有一个父组件。例如,如果相同的组件必须显示在两个不同的帧中,则需要此组件的两个实例。

答案 1 :(得分:0)

除了单例模式带来的耦合问题(=程序中的许多类依赖于您的工厂 - >如果您的工厂发生变化,系统的许多部分都会受到影响。),您的单件工厂应该工作在多线程环境中。

但要注意不要优化它。有一种称为双重检查锁定的技术,用于优化您的解决方案以获得更高程度的并发性,但它有非常微妙的问题。如果您有兴趣,请参阅此声明(并注明签名的人):http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

为了摆脱与工厂的耦合,我宁愿在一些顶级类中创建共享结构(表,监听器,框架),这些类也创建需要引用这些结构的对象。并将结构传递给它们的构造函数。但这只是一个建议,我不知道该计划的整体结构。