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.

有帮助吗?

解决方案

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.

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top