5

Я понимаю, что одним из основных преимуществ Factory Method по сравнению с Simple Factory является то, что он не нарушает открытый принцип SOLID. То есть, первый не требует модификации оператора switch при добавлении новых типов.Простая фабрика против фабричного метода: выключение оператора на заводе против клиента

Существует одна деталь, на которой я надеюсь получить разъяснения. Если бы я должен был использовать простой завод, я бы завод, как это (упрощенный):

public class ObjectFactory { 
    public static IObject CreateObject(ObjectTypeEnum objectType) { 
     switch (objectType) { 
      case TypeA: 
       return ObjectA; 
       break; 
      case TypeB: 
       return ObjectB; 
       break; 
      case TypeC: 
       return ObjectC; 
       break; 
     } 
    } 
} 

и клиент назвал бы это так:

IObject myObject = ObjectFactory.CreateObject(objectType); 

Недостаток в литературе является то, что CreateObject необходимо будет изменить при добавлении новых типов объектов.

Но с фабричным способом, что мы просто не двигать эту модификацию с завода к клиенту, как этот (клиентский код):

IObject myObject; 
switch (objectType) { 
      case TypeA: 
       myObject = ObjectAFactory.CreateObject(); 
       break; 
      case TypeB: 
       myObject = ObjectBFactory.CreateObject(); 
       break; 
      case TypeC: 
       myObject = ObjectCFactory.CreateObject(); 
       break; 
} 

В этом случае клиент должен быть изменен каждый раз, когда добавляется новый тип, а в предыдущем случае завод должен был быть изменен. Так в чем же преимущество тогда одного над другим? Пожалуйста, не отмечайте это как дубликат, я просмотрел много сообщений о фабриках, и никто не обращается к этому конкретному различию.

Есть ли лучшее решение, которое не нарушает принцип Open/Closed на стороне клиента или на заводе?

ответ

1

Стандарт Abstract Factory Дизайн-шаблон не помогает?
упрощенный Java-код:

public interface IFactory { 
    IObject createObject(); 
} 

public class FactoryA implements IFactory { 
    public IObject createObject() { 
     return new ObjectA(); 
    } 
} 

public class FactoryB implements IFactory { 
    public IObject createObject() { 
     return new ObjectB(); 
    } 
} 

Client is configured (injected) with the needed Factory at run-time 
    IFactory myFactory = ... // new FactoryA(); 
... 
IObject myObject = myFactory.createObject(); 
... 

Смотрите также GoF Design Patterns памяти/Abstract Factory в http://w3sdesign.com.

VARIANT 2
Вместо использования типов объектов перечисления, определите типы объектов с помощью полиморфизма (чтобы избежать операторов switch). упрощенный Java-код:

public interface IObjectType { 
    int getObjectType(); 
    IObject createObject(); 
} 

public class ObjectTypeA implements IObjectType { 
    ... 
    public IObject createObject() { 
     return new ObjectA(); 
    } 
} 

public class ObjectTypeB implements IObjectType { 
    ... 
    public IObject createObject() { 
     return new ObjectB(); 
    } 
} 

Client determines object type 
IObjectType myObjectType = ... // new ObjectTypeA(); 
... 
IObject myObject = myObjectType.createObject(); 
... 

Мой вывод:
Я думаю, лучшим решением было бы создавать свои типы с полиморфизмом вместо использования перечислений Constans. Это позволит избежать операторов switch и не будет нарушать принцип Open/Closed на стороне клиента или производителя.

+0

Это по существу вариант моего второго варианта выше. Причина, по которой это не работает для меня, заключается в том, что в моем случае «клиент» фабрики фактически является веб-API. Клиент Web API («клиентский клиент») будет определяющим фактором для типа объекта, поэтому я не вижу способа его инжекции, не делая переключения на тип объекта, независимо от того, находится ли он в api, который создает IFactory или на самом заводе. – mayabelle

+0

Как клиенты определяют тип объекта? – GFranke

+0

Клиент передает тип объекта, который они хотят получить в api. Тип объекта - значение перечисления. – mayabelle