How to refactor a class hierarchy of singletons where each class has a getInstance() method?
我继承了一个特定的单例类层次结构,其声明总结如下(还有更多的实现——我只是展示了演示问题的最小集合)。对我来说,这简直是天赐良机,最重要的是,单例继承自基类中的EDOCX1[0]的方法,它的值在子类的静态初始值设定项中被覆盖。
如果所有的实现都在
但是实现可以在
第一个接口:
1 2 3 4 5 6 |
第二接口:
1 2 3 4 5 6 |
第一次实施:
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。如果这不合适,那么可以考虑使用弹簧容器或类似的框架。