工厂类的动态行为

时间:2010-06-18 06:31:55

标签: java design-patterns oop

我有一个工厂类,可以提供一系列属性。

现在,属性可能来自数据库或属性文件。

这就是我想出来的。

public class Factory {

    private static final INSTANCE = new Factory(source);

    private Factory(DbSource source) {
        // read from db, save properties
    }

    private Factory(FileSource source) {
        // read from file, save properties
    }

    // getInstance() and getProperties() here
}

根据环境在这些行为之间切换的简洁方法是什么。 我想避免每次都重新编译该类。

3 个答案:

答案 0 :(得分:6)

依赖注入是实现它的方法。

通常情况下,在你的情况下使用依赖注入看起来像这样(例如对于Spring DI,对于Guice来说看起来会有些不同,但想法是一样的):

public interface Factory {
    Properties getProperties();
}

public class DBFactory implements Factory {
    Properties getProperties() {
        //DB implementation
    }
}

public class FileFactory implements Factory {
    Properties getProperties() {
        //File implementation
    }
}

public SomeClassUsingFactory {
    private Factory propertyFactory;

    public void setPropertyFactory(Factory propertyFactory) {
        this.propertyFactory = propertyFactory;
    }

    public void someMainMethod() {
        propertyFactory.getProperties();
    }
}

//Spring context config
<!-- create a bean of DBFactory (in spring 'memory') -->
  <bean id="dbPropertyFactory"
    class="my.package.DBFactory">
    <constructor-arg>
      <list>
        <value>Some constructor argument if needed</value>
      </list>
    </constructor-arg>
  </bean>
 <!-- create a bean of FileFactory (in spring 'memory') -->
  <bean id="filePropertyFactory"
    class="my.package.FileFactory">
    <constructor-arg>
      <list>
        <value>Some constructor argument if needed</value>
      </list>
    </constructor-arg>
  </bean>
<!-- create a bean of SomeClassUsingFactory -->
  <bean id="MainClass"
    class="my.package.SomeClassUsingFactory">
    <!-- specify which bean to give to this class -->
    <property name="propertyFactory" ref="dbPropertyFactory" />
  </bean>

然后,在不同的环境中,您只需将xml配置文件与将其设置为filePropertyFactory的其他文件交换,然后将其传递给SomeClassUsingFactory。

答案 1 :(得分:1)

简单地说,不要使用单身人士。

“从上面参数化”。在有意义的代码中的某个位置构建所需的实现。将实例传递给那些在构造时需要它的对象。

答案 2 :(得分:0)

您可以定义类似的内容:

public abstract Factory  {
    // define all factory methods here
    public static Factory getFactory(FactoryType type, Object source) {
        if (type == FactoryType.DB) {
             return new DbFactory(source);
        }
        if (type == FactoryType.PROPERTIES) {
             return new PropertiesFactory(source);
        }
    }
}

public DbFactory implements AbstractFactory { .. }
public PropertiesFactory implements AbstractFactory { .. }
  • 您可以使用instanceof代替enum
  • 如果您希望您的工厂是单件,请使用静态方法替换实例化(new