使用反射的Factory Pattern与Singleton Pattern的冲突问题

02-10-23 CrazyJavar
具体情况如下:

有个产品系
class X
{
...
}

class A extends X
{
...
}

class B extends X
{
...
}

同类的产品还有C, D, E...等等

该组类的责任是管理web app中的xml文件

为避免管理冲突,对其所有方法synchronized,并使用Singleton Pattern

使得每次都只有一个实例在work

现有工厂方法

class XFactory
{
public X getX(String key)
{
...
}
}

本来我根据传入的参数key生成具体的X系子类
if (key.equals("xxxxx")) then 方法

但是考虑X系的子类很多,于是改用反射,key就是类的全名

X = Class.forName(key).newInstance();

但问题是反射一定要求类的构造器不能private

因此就和X系类的Singleton Pattern冲突了

请教各位DP牛人

如何解决这个问题呢?

banq
2002-10-23 13:01
不一定要用singleton
使用reflect的方法定义static也可以啊。

CrazyJavar
2002-10-23 15:44
板桥大哥

小弟不是很明白你的话

可否写点关键代码看看

非常感谢

谢谢

CrazyJavar
2002-10-23 16:44
Reflection API 在运行时无法获取私有成员的值。

CrazyJavar
2002-10-23 16:44
package test;

import utilities.Recorder;
import java.lang.reflect.*;

public class Reflector
{
public static void main(String[] args)
{
try
{
Class targetClass = Class.forName("test.RF");
Method m = targetClass.getDeclaredMethod("out", null);
m.invoke(null, null);
}
catch (Exception e)
{
Recorder.myLog.debug("Caught an exception : ", e);
}
}
}


class RF
{
static void out()
{
Recorder.myLog.debug("RF.out()");
}

private SubRF()
{
Recorder.myLog.debug("new sub instance");
}
}

class SubRF extends RF
{
static void out()
{
Recorder.myLog.debug("SubRF.out()");
}

private SubRF()
{
Recorder.myLog.debug("new sub instance");
}
}

上面这个程序编译错误
因为构造器的权限为private

vic
2002-10-24 11:35
你为什么要把SubRF 等子类的构造器设置为private?
我想这么做也能达到你的目的,也就是:
1.保证一个类的实例
2.保证类方法为同步(这个就不用说了)

第一个问题的解决方法简单点来讲就是在每个子类都外加一个类
来帮助实现singleton和公共构造器的适配
举例如下:

public class SubRFHelper {
  private static SubRF subRF = null;
  private static Object lock = new Object();
  public SubRFHelper() { //[b]注意[/a]
    if (subRF == null) {
      synchronized(lock) {
        if (subRF == null) {
          subRF == new SubRF();
        }
      }
    }

  }

  public SubRF getRF() {
    return subRF;
  }

}
<p class="indent">


好处:
你的工厂方法实现起来就比较简单,可以利用反射了
但是反射使用的类名94 xxxHelper
缺点:
增加了一层的类,可能会n多:)

实际就是将具体工作转移化,你的需求已经达到,
好不好自己决定,呵呵。。。

CrazyJavar
2002-10-24 11:51
楼上的哥们提出的是个办法

不过这类一多,会“爆炸”的啊

CrazyJavar
2002-10-24 11:52
板桥大哥怎么不出声了啊

请您指教一二吧

vic
2002-10-24 11:56
还有一种解决方法
就是你把你的factory和你的类都放在一个包下
把构造器设为friendly

CrazyJavar
2002-10-24 13:08
你这么解决不安全

假如另外一个程序员在这个包内开发

他就可以new出第2个第3个实例了

vic
2002-10-24 17:19
至于包你可以人为控制!
你又想功能灵活,又想省事,恐怕。。。:)