Модельный паттерн «Фабрика» проистекает из почти догматического убеждения программистов на языках «C-стиля» (C / C ++, C #, Java), что использование «нового» ключевого слова плохо, и его следует избегать любой ценой (или по крайней мере). наименее централизованный). Это, в свою очередь, исходит из ультра-строгой интерпретации принципа единой ответственности («S» SOLID), а также принципа обращения зависимостей («D»). Проще говоря, SRP говорит, что в идеале у объекта кода должна быть одна «причина для изменения» и только одна; эта «причина изменения» является центральной целью этого объекта, его «ответственностью» в кодовой базе и всем остальным, что требует изменения кода, не должно требовать открытия этого файла класса. DIP еще проще; объект кода никогда не должен зависеть от другого конкретного объекта,
Например, используя «new» и открытый конструктор, вы связываете вызывающий код с конкретным методом конструирования конкретного конкретного класса. Теперь ваш код должен знать, что класс MyFooObject существует и имеет конструктор, который принимает строку и int. Если этому конструктору когда-либо понадобится дополнительная информация, все виды использования конструктора должны быть обновлены, чтобы передать эту информацию, включая ту, которую вы пишете сейчас, и поэтому они должны иметь что-то допустимое для передачи, и поэтому они должны либо иметь это или быть изменено, чтобы получить это (добавление большего количества обязанностей к потребляющим объектам). Кроме того, если MyFooObject когда-либо будет заменен в кодовой базе на BetterFooObject, все виды использования старого класса должны измениться, чтобы создать новый объект вместо старого.
Таким образом, вместо этого все потребители MyFooObject должны напрямую зависеть от «IFooObject», который определяет поведение реализации классов, включая MyFooObject. Теперь потребители IFooObjects не могут просто создать IFooObject (не зная, что конкретный конкретный класс является IFooObject, который им не нужен), поэтому вместо этого им должен быть предоставлен экземпляр класса или метода, реализующего IFooObject. извне, другим объектом, который несет ответственность за знание того, как создать правильный IFooObject для обстоятельств, которые, на нашем языке, обычно называют Factory.
Теперь вот где теория встречается с реальностью; объект никогда не может быть закрыт для всех типов изменений все время. Например, IFooObject теперь является дополнительным объектом кода в базе кода, который должен меняться всякий раз, когда изменяется интерфейс, требуемый потребителями или реализациями IFooObjects. Это вводит новый уровень сложности, связанный с изменением способа взаимодействия объектов друг с другом в этой абстракции. Кроме того, потребители все равно должны будут измениться, и более глубоко, если сам интерфейс будет заменен на новый.
Хороший кодер знает, как сбалансировать YAGNI («Вам это не нужно») с SOLID, анализируя дизайн и находя места, которые с большой вероятностью могут измениться определенным образом, и реорганизуя их, чтобы они были более терпимыми к что тип изменения, потому что в этом случае «вы это собираетесь это нужно».