关于java:如何重构单个类的层次结构,其中每个类都有一个getInstance()方法?

How to refactor a class hierarchy of singletons where each class has a getInstance() method?

我继承了一个特定的单例类层次结构,其声明总结如下(还有更多的实现——我只是展示了演示问题的最小集合)。对我来说,这简直是天赐良机,最重要的是,单例继承自基类中的EDOCX1[0]的方法,它的值在子类的静态初始值设定项中被覆盖。

如果所有的实现都在foo.common父包中,我将考虑从它们中删除instance成员和getInstance()方法,使类和它们的构造函数包本地化,并在foo.common中拥有一些公共工厂类,创建每个实例的单个实例,保留每个接口的单个实例。rnally(通过它是IReadOnlyIReadWrite的实现进行分区)并提供一些公共查找方法,在这些方法中,基于某种枚举,它会将请求的实现作为接口类型返回。

但是实现可以在foo.common之外进行,并且不允许foo.common依赖于这种"更具体"的包,因为foo.common是为一系列应用程序所通用的东西而设计的。所以有些简单的事情是做不到的。那么呢?

第一个接口:

1
2
3
4
5
6
package foo.common.config;
public interface IReadOnly
{
    void load();
    String getVal(String key);
}

第二接口:

1
2
3
4
5
6
package foo.common.config;
public interface IReadWrite extends IReadOnly
{
    void save();
    void setVal(String key, String value);
}

第一次实施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package foo.common.config;
public class ReadOnlyImpl implements IReadOnly
{
    protected static IReadOnly instance;

    static {
        instance = new ReadOnlyImpl();
    }

    public static IReadOnly getInstance() {
        return instance;
    }

    protected ReadOnlyImpl() {}

    // implement methods in IReadOnly
}

第二次实施

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package foo.common.config;
public class ReadWriteImpl extends ReadOnlyImpl implements IReadWrite
{
    static {
        instance = new ReadWriteImpl();
    }

    public static IReadWrite getInstance() {
        return (IReadWrite) instance;
    }

    protected ReadWriteImpl() {
        super();
    }

    // Implement methods in IReadWrite
}

第三次实施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// While things in this package can depend
// on things in foo.common, nothing in
// foo.common is allowed to depend on this package.
package foo.apps.someapp;
public class MoreSpecificReadWriteImpl extends ReadWriteImpl
{
    static {
        instance = new MoreSpecificReadWriteImpl();
    }

    public static IReadWrite getInstance() {
        return (IReadWrite) instance;
    }

    protected MoreSpecificReadWrite() {
        super();
    }

    // Override superclass methods to do something specific
}


把包foo.apps.someapp放在一边,包foo.common.config的设计是错误的。

1
2
3
4
5
IReadOnly o1=ReadOnlyImpl.getInstance(); // ok, returns ReadOnlyImpl
...
ReadWrite o2=ReadWriteImpl.getInstance(); // ok, returns ReadWriteImpl
...
IReadOnly o3=ReadOnlyImpl.getInstance(); // bad, returns ReadWriteImpl, the same as o2.

原因是所有类都使用相同的静态变量readOnlyImpl.instance。我将在所有类中使用单独的变量,包括moreSpecificReadWriteImpl。如果这不合适,那么可以考虑使用弹簧容器或类似的框架。