Java 在每个类都有一个getInstance()方法的情况下,如何重构单例的类层次结构?

Java 在每个类都有一个getInstance()方法的情况下,如何重构单例的类层次结构?,java,inheritance,refactoring,singleton,Java,Inheritance,Refactoring,Singleton,我继承了一个特定的单例类层次结构,其声明总结如下(还有更多的实现——我只是展示最小集来演示这个问题)。对我来说,这简直是天方夜谭,最重要的是因为单例是从继承来的,而且基类中的instance在子类的静态初始值设定项中重写了它的值 如果所有实现都在 fo.Ung/父包中,我会考虑只从它们中删除实例< /COD>成员和 GETStasnSee()/Cux>方法,使类和它们的构造函数封装为本地,并在 Fo.Ung/中创建一些公共工厂类。在内部保留每个实例的单个实例(根据它是IReadOnly还是IRe

我继承了一个特定的单例类层次结构,其声明总结如下(还有更多的实现——我只是展示最小集来演示这个问题)。对我来说,这简直是天方夜谭,最重要的是因为单例是从继承来的,而且基类中的
instance
在子类的静态初始值设定项中重写了它的值

如果所有实现都在<代码> fo.Ung/<代码>父包中,我会考虑只从它们中删除<代码>实例< /COD>成员和<代码> GETStasnSee()/Cux>方法,使类和它们的构造函数封装为本地,并在<代码> Fo.Ung/<代码>中创建一些公共工厂类。在内部保留每个实例的单个实例(根据它是

IReadOnly
还是
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 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
}
// 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
}
第二次实施

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
}
第三次执行:

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
}
// 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的设计是错误的

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容器或类似的框架。

将包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容器或类似的框架。

最后一行是否有输入错误?和第一行一样,没有打字错误。它不一样:o1和o3。你的最后一行有打字错误吗?和第一行一样,没有打字错误。o1和o3是不同的。你能解释一下为什么/如何重构它吗?我真的看不出它有什么问题。你能解释一下为什么/如何重构它吗?我真的看不出有什么问题。