та не плохие, только когда они нужны.. например у тебя есть сущность, тот же автомобиль.. автомобиль может быть новым, с салона, а может быть БУшный от перекупа
у тебя есть 2 сценария, когда автомобиль попадает в твою систему. Когда продаваны в салоне заносят по прибытию новой партии или обычные люди или перекупы свою дасточку внести хотят
в сценарии нового авто будет что-то типа
Car::new($model, $color)
для БУ будет
Car::used($model, $color, $year, ...)
а под капотом и тот и другой метод будут вызывать
return new self($model, $color ....)
просто для новой, пробег к примеру будет сразу 0 идти, год выпуска - текущий и т.д
метод для создания БУ машины будет прокидывать явно переданные поля
Пример надуманный конечно, но идея такая. У тебя есть так называемые именованные конструкторы
Это по сути фабричные методы и они полезны, когда у тебя есть все необходимы данные для создания объекта сразу. Тогда нет смысла делать фабрику, которая и так прокинет все эти данные в конструктор и на этом все
Если же у тебя появляется доп логика, например, сходить в другую систему по АПИ и получить какие-то доп данные. Вызвать какой-то доп сервис-калькулятор и посчитать сумму с налогами для страны пользователя - это все уезжает в фабрику