В каких случаях имеет смысл использовать фабричные классы вместо статических функций? - PullRequest
5 голосов
/ 02 апреля 2010

В настоящее время я создал класс ABCFactory, в котором есть один метод создания объектов ABC. Теперь, когда я думаю об этом, возможно, вместо фабрики, я мог бы просто сделать статический метод в моем методе ABC. Каковы "за" и "против" при внесении этих изменений? Не приведет ли это к тому же? Я не предвижу, что другие классы наследуют ABC, но никто не знает!

Спасибо

Ответы [ 6 ]

4 голосов
/ 02 апреля 2010

Наличие одного статического метода значительно затрудняет его тестирование, в то время как наличие инстанцируемого объекта облегчает его тестирование. Кроме того, внедрение нестабильности позже является более подходящим вариантом для нестатического решения.

Конечно, если вам это не нужно, тогда это не очень хорошие аргументы.

3 голосов
/ 02 апреля 2010

Основным преимуществом фабричного метода является возможность скрыть ссылку на определенный класс за интерфейсом. Поскольку статические методы не могут быть частью интерфейса, статические фабричные методы в основном такие же, как и сам метод конструктора. Единственное полезное применение методов статической фабрики - предоставить доступ к закрытому конструктору, который обычно используется для реализации одноэлементного шаблона.

2 голосов
/ 02 апреля 2010

В действительности, если вы хотите получить преимущества фабричного класса, вам нужен статический метод в своем собственном классе. Это позволит вам позже создавать новые фабричные классы или реконфигурировать существующий, чтобы получить другое поведение. Например, один фабричный класс может создавать Unicorns, которые реализуют интерфейс IFourHoovedAnimal. Возможно, у вас написан алгоритм, который работает с IFourHoovedAnimal и нуждается в его создании. Позже вы можете создать новый класс фабрики, который вместо этого создает экземпляры Pegasus, которые также реализуют IFourHoovedAnimal. Старый алгоритм теперь можно повторно использовать для Pegasus, просто используя новую фабрику! Чтобы это работало, PegasusFactory и UnicornFactory должны наследовать от некоторого общего базового класса (обычно абстрактного класса).

Итак, вы видите, поместив статический метод в его собственный фабричный класс, вы можете заменить фабричные классы новыми, чтобы использовать старые алгоритмы. Это также работает для улучшения тестируемости, потому что теперь модульные тесты можно использовать для фабрики, которая создает фиктивные объекты.

Я делал это раньше (статический метод фабрики для класса, экземпляры которого вы создаете) для очень маленьких проектов, но это было только потому, что мне это было нужно, чтобы помочь в рефакторинге какого-то старого кода, но сохранить изменения до минимума. В основном в этом случае я выделил кусок кода, который создал кучу элементов управления ASP.NET, и поместил все эти элементы управления в пользовательский элемент управления. Я хотел сделать свой новый пользовательский элемент управления основанным на свойствах, но старому унаследованному коду было проще создать пользовательский элемент управления с помощью конструктора на основе параметров.

Итак, я создал статический метод фабрики, который взял все параметры, а затем создал пользовательский элемент управления и установил его свойства на основе параметров. В старом унаследованном коде этот статический метод использовался для создания пользовательского элемента управления, а в будущем коде вместо него использовались бы свойства «красивее».

1 голос
/ 02 апреля 2010

Чрезмерное использование шаблонов проектирования опасно, и шаблоны проектирования для творчества имеют смысл, когда у вас есть иерархии классов с определенными интерфейсами или вам нужно создавать довольно сложные объекты.Если у вас простой дизайн, используйте простые решения.Поэтому, в вашем случае, Factory Method будет достаточно

Да, вы правы, это другой шаблон проектирования :)

1 голос
/ 02 апреля 2010

"D" в ТВЕРДЫЕ Принципы объектно-ориентированного проектирования дяди Боба - это "Принцип инверсии зависимостей" Зависит от абстракций, а не от конкрементов. Чрезвычайное следование этому принципу может привести к тому, что ваш основной класс создаст все ваши фабрики, причем каждая фабрика будет использовать другие фабрики через интерфейсы. Единственное появление «нового» (создание конкретных объектов) будет в вашем основном классе и на ваших фабриках. Все ваши объекты будут работать с интерфейсами (абстракциями), с конкретными зависимостями, полученными из поставляемых реализаций фабрики.

Вы можете очень легко настроить или предоставить несколько основных классов, настроенных для различных сценариев.

1 голос
/ 02 апреля 2010

Для конкретных классов фабричные методы на самом деле являются просто методом косвенного обращения к созданию фактического типа (что не означает, что они бесполезны, но, как вы обнаружили, фабричный метод действительно может быть в любом месте ).

Хотя фабричный метод действительно сияет, это когда ваш метод создает экземпляры типа интерфейса.

...