1

我继承了一个特定的单例类层次结构,其声明总结如下(还有更多的实现——我只是展示了最小的集合来演示问题)。对我来说,它闻起来像天堂,首先是因为继承了单例,以及instance基类中的方式在子类的静态初始化程序中覆盖了它的值。

如果所有实现都在foo.common父包中,我会考虑从它们中删除instance成员和getInstance()方法,使类及其构造函数成为本地包,并让一些公共工厂类foo.common创建每个实例的单个实例,保留该单个实例每个内部(根据它是否是IReadOnlyor的实现来划分IReadWrite)并提供几个公共查找方法,在这些方法中,基于某些枚举,它将返回所要求的实现作为接口类型。

但是实现可以在这些“更具体”的包之外foo.common并且foo.common不允许依赖于这些包,因为foo.common它是为一堆应用程序所共有的东西而设计的。所以这么简单的事情是做不来的。然后怎样呢?

第一个界面:

package foo.common.config;
public interface IReadOnly
{
    void load();
    String getVal(String key);
}

第二个界面:

package foo.common.config;
public interface IReadWrite extends IReadOnly
{
    void save();
    void setVal(String key, String value);
}

第一次实现:

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
}

第二次实施

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
}

第三个实现:

// 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
}
4

1 回答 1

1

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

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。如果这不合适,那么考虑使用 Spring 容器或类似的框架。

于 2012-05-04T05:02:25.297 回答