динамическое поведение фабричного класса - PullRequest
2 голосов
/ 18 июня 2010

У меня есть фабричный класс, который предоставляет кучу свойств.

Теперь свойства могут поступать либо из базы данных, либо из файла свойств.

Это то, что я придумал.

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 ]

6 голосов
/ 18 июня 2010

Dependency Injection - это способ сделать это.

Как правило, использование внедрения зависимостей в вашей ситуации выглядело бы так (пример для 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 голос
/ 18 июня 2010

Просто не используйте синглтоны.

"Параметр сверху".Создайте требуемую реализацию в том месте кода, где это имеет смысл.Передайте экземпляр тем объектам, которые в нем нуждаются, поскольку они созданы.

0 голосов
/ 18 июня 2010

Вы можете определить что-то вроде:

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) статическим методом
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...