Фабричный образец решит мою проблему? - PullRequest
5 голосов
/ 03 августа 2010

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

У меня возникают проблемы, когда разные конкретные реализации требуют разных параметровво время выполнения.

Этот пример (C #) подойдет:

public enum ProductCategory
{
    Modem,
    Keyboard,
    Monitor
}

public class SerialNumberValidatorFactory()
{
    public ISerialNumberValidator CreateValidator(ProductCategory productCategory)
    {
        switch (productCategory)
        {
            case ProductCategory.Modem:
                return new ModemSerialNumberValidator();
            case ProductCategory.Keyboard:
                return new KeyboardSerialNumberValidator();
            case ProductCategory.Monitor:
                return new MonitorSerialNumberValidator();
            default:
                throw new ArgumentException("productType", string.Format("Product category not supported for serial number validation: {0}", productCategory))
        }
    }
}

Однако что произойдет, если конкретные реализации имеют разные аргументы конструктора?Я не могу передать все значения методу SerialNumberValidatorFactory.CreateValidator(), так как мне продолжить?

Я слышал, что шаблон Abstract Factory должен решить эту проблему, но я не уверен, какреализовать это правильно.

Ответы [ 2 ]

2 голосов
/ 03 августа 2010

То, что вы используете, - это шаблон фабричного метода, то, что вы должны использовать, это абстрактная фабрика

В абстрактной фабрике вы предоставляете фабричный класс для каждой конкретной реализации:

Таким образом, ваш код становится: (простите код, но обоснование то же самое)

public class SerialNumberValidatorFactory
{
    public static SerialNumberValidatorFactory newInstance(
           ProductCategory productCategory)
    {
        switch (productCategory)
        {
            case ProductCategory.Modem:
                return new ModemValidatorFactory();
            ....
        }
    }

    public abstract ISerialNumberValidator createValidator();
}

public class ModemValidatorFactory extends SerialNumberValidatorFactory
{
   public ISerialNumberValidator createValidator() 
   {
      return new ModemSerialNumberValidator("model", "number");
   }
}

ISerialNumberValidator = SerialNumberValidatorFactory.newInstance(productCategory).createValidator()
2 голосов
/ 03 августа 2010

Вы всегда можете создать контейнер настроек для передачи методу CreateValidator.Начните с базового IValidatorSettings, затем создайте IModemSerialNumberValidatorSettings и т. Д., Ваш CreateValidator может принять ProductType и IValidatorSettings аргументы.

Ваши конкретные классы для валидаторов примут свои IXXXValidatorSettingsinterface как единственный аргумент конструктора.

Кроме того, вы можете создать фабрику IValidatorSettings.

Я думаю, что абстрактная фабрика - это фабрика, которая создает фабрику для обработки заданного набора типов.- не уверен, применимо ли это в вашем сценарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...