Factory of Domain对象的这种设计是否有意义?

时间:2015-10-09 13:27:04

标签: java dependency-injection factory factory-pattern

我正在为我的域对象制作工厂。域对象是原型对象,因此在业务逻辑运行时它们会经常被实例化。以下是设计:

1)一些域接口和类:

public interface FirstDomainInterface {}

public class FirstDomainClass implements FirstDomainInterface {

    private String firstName;

    private int phoneNumber;

    public FirstDomainClass(String firstName, int phoneNumber) {
        super();
        this.firstName = firstName;
        this.phoneNumber = phoneNumber;
    }

public interface SecondInterface {}

public class SecondDomainClass implements SecondInterface {

    private long accountNumber;

    private BigDecimal balance;

    public SecondDomainClass(long accountNumber, BigDecimal balance) {
        super();
        this.accountNumber = accountNumber;
        this.balance = balance;
}

2)接口声明方法,它返回工厂所需对象类型的构造函数

public interface ObjectConfig {
    public Constructor<?> getConstructor() throws NoSuchMethodException, SecurityException;
}

3)在第二点声明的接口的实现

public enum FirstModuleConfig implements ObjectConfig {

    FirstTypeObject {

        @Override
        public Constructor<?> getConstructor() throws NoSuchMethodException, SecurityException {
            Constructor<FirstDomainClass> constructor = FirstDomainClass.class.getConstructor(String.class, int.class);
            return constructor;
        }           
    }
}

public enum SecondModuleConfig implements ObjectConfig {

    SecondTypeObject {

        @Override
        public Constructor<?> getConstructor() throws NoSuchMethodException, SecurityException {
            Constructor<SecondDomainClass> constructor = SecondDomainClass.class.getConstructor(long.class, BigDecimal.class);
            return constructor;
        }           
    }
}

4)实例化对象的工厂

public class Factory {

    public Object createInstance(ObjectConfig config, Object...args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException  {

        return config.getConstructor().newInstance(args);
    }
}

5)最后使用工厂:

public class FactoryTest {

    @Test
    public void test() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        Factory factory = new Factory();

        FirstDomainInterface firstTypeObject = (FirstDomainInterface) factory.createInstance(FirstModuleConfig.FirstTypeObject,"myName",12345);

        SecondInterface secondTypeObject = (SecondInterface)factory.createInstance(SecondModuleConfig.SecondTypeObject, 123455232l,BigDecimal.ZERO);

    }

}

这看起来怎么样?

我看到的潜在优势:

1)对于我创建的每个新接口/类,我只需要在其中一个实现ObjectConfig接口的Enum中声明它的构造函数

2)给我一个干净的设计。我不必为我的所有域对象实现一个完整的工厂。只需要实现一个返回构造函数用于实例化的方法。

3)可以将此单个Factory注入需要创建域对象的所有服务

我怀疑的缺点:

1)由于类强制转换,参数不匹配等导致的潜在运行时异常。

2)由于使用反射而变慢?

请注意,这意味着用于通过服务层实例化原型域/业务对象。对于单例服务和控制器bean,我使用的是Spring Container,它可以在启动时准备好这些bean。

谢谢!

1 个答案:

答案 0 :(得分:0)

使用静态工厂有几个好处。使用工厂创建类似乎是一种很好的方法。

但是,我会在您的实施中提出以下意见。

  1. 考虑将公共构造函数限制为包私有,并仅允许使用Factory方法。工厂应该在同一个包装中。因此,您还可以创建一个实例控制工厂,并强制一致使用工厂方法。否则,团队中的其他程序员(或将来的某些程序员)最终可能会同时使用工厂和构造函数。

  2. 使用以下功能:

  3.   

    public Object createInstance(ObjectConfig config,Object ... args)

    您在编程期间节省了一些打字时间,但是您在编译时会丢失很多编译器所做的检查,并且可能会增加更多运行时错误的机会。一般来说,这种做法应该避免。

    1. 性能肯定更差,因此如果您必须维护代码,为什么不为每个类添加专用的工厂方法。它只是一个委托调用包私有构造函数。简单易读,易于编写。
    2. Joshua Bloch的Effective Java Second Edition第一部分中有关于工厂方法的很好的描述。你可以在继续之前检查它。

      这些是一些通用的注释,但是您在设计中采用的路径与应用程序的服务目的有关。

      我会提出类似的建议:

      public class Factory{
        public InterfaceA createNewInterfaceA(int argumentInt,String argumentString){
          return new ClassImplementingInterfaceA();
        }
        public InterfaceA createNewInterfaceA(int argumentInt,double argumentDouble){
          return new ClassImplementingInterfaceA(argumentInt,argumentDouble);
        }
      
      }
      
       ...similar for all other interfaces