Вы правы, что фабрика сама нарушает принцип ОТКРЫТО / ЗАКРЫТО, поскольку она статически связана с типами, которые она создает.То же самое происходит в вашей абстрактной фабрике, поскольку вы только вводите дополнительный уровень абстракции.Не фабрика решает, какой тип создавать, а код, который создает фабрику.
Но на самом деле у вас есть , чтобы выполнить переключение где-нибудь.Этот код, вероятно, нарушит некоторые принципы.Это компромисс, который вы должны делать довольно часто в программировании.Однако считается более низкой цена за более высокий выигрыш: вместо того, чтобы менять каждый код клиента, когда вы вводите новый тип, вы должны сделать это только один раз на фабрике .Таким образом, весь потребительский код может остаться без изменений.
Еще одно преимущество заключается в том, что ваш клиентский код полностью не знает о реальном классе.Это не нужно знать.На самом деле реальный класс может быть даже произвольной насмешкой.Таким образом, вы можете протестировать свой клиентский код, даже если зависимость (фактически класс, который реализует IFan
) еще не существует или только частично разработана другим членом команды:
// there´s currently no valid implementation for the interface,
// however we don´t care for it, we´re just interested in our own class
// Thus we mock that dependency away
IFan mock = new Mock<IFan>();
systemUnderTest.DoSomething(mock.Object);