В выходные я писал некоторый код, и мне захотелось написать фабрику как статический метод в базовом классе.
Мой вопрос состоит в том, чтобы просто знать, является ли это актуальным подходом?
Я чувствую, что это не может быть связано с тем, что базовый класс знает о производном классе.
Тем не менее, я не уверен, что проще получить тот же результат. Целый другой фабричный класс кажется (по крайней мере мне) ненужной сложностью (?)
Что-то вроде:
class Animal
{
public static Animal CreateAnimal(string name)
{
switch(name)
{
case "Shark":
return new SeaAnimal();
break;
case "Dog":
return new LandAnimal();
break;
default:
throw new Exception("unknown animal");
}
}
}
class LandAnimal : Animal
{
}
class SeaAnimal : Animal
{
}
c#
class-design
Аарон Анодид
источник
источник
Ответы:
Что ж, преимущество отдельного фабричного класса в том, что его можно смоделировать в модульных тестах.
Но если вы этого не сделаете или не сделаете полиморфным каким-либо другим способом, тогда статический метод Factory для самого класса в порядке.
источник
Вы можете использовать Generics, чтобы избежать оператора switch и отделить последующие реализации от базового класса:
Использование:
или
источник
В крайнем случае, фабрика также может быть универсальной.
Затем можно создать фабрику объектов любого типа, которая, в свою очередь, может создать объект любого типа. Я не уверен, если это проще, это, безусловно, более общий характер.
Я не вижу ничего плохого в операторе switch для небольшой фабричной реализации. Как только вы разберетесь с большим количеством объектов или, возможно, с различными иерархиями классов объектов, я думаю, что более общий подход лучше подходит.
источник
Плохая идея. Во-первых, это нарушает принцип открытого-закрытого. Для любого нового животного вам придется снова связываться с вашим базовым классом, и вы можете его сломать. Зависимости пойдут не в ту сторону.
Если вам нужно создать животных из конфигурации, такая конструкция будет в порядке, хотя использование рефлексии для получения типа, соответствующего имени, и создание его экземпляра с использованием полученной информации о типе будет лучшим вариантом.
Но вы все равно должны создать выделенный фабричный класс, отвязанный от иерархии классов животных, и вернуть интерфейс IAnimal, а не базовый тип. Тогда это станет полезным, вы бы достигли некоторой развязки.
источник
Этот вопрос для меня актуален - вчера я писал почти такой код. Просто замените «Animal» тем, что имеет отношение к моему проекту, хотя я остановлюсь на «Animal» для обсуждения здесь. Вместо оператора «switch» у меня была несколько более сложная серия операторов «if», включающая не только сравнение одной переменной с определенными фиксированными значениями. Но это деталь. Статический фабричный метод казался изящным способом проектирования вещей, так как дизайн возник из рефакторинга ранних быстрых и грязных кодов.
Я отклонил этот проект на основании того, что базовый класс обладает знанием производного класса. Если классы LandAnimal и SeaAnimal маленькие, аккуратные и простые, они могут находиться в одном исходном файле. Но у меня есть большие грязные методы для чтения текстовых файлов, не соответствующих каким-либо официально определенным стандартам - я хочу, чтобы мой класс LandAnimal находился в его собственном исходном файле.
Это приводит к циклической зависимости файла - LandAnimal происходит от Animal, но Animal уже должен знать, что существуют LandAnimal, SeaAnimal и пятнадцать других классов. Я вытащил фабричный метод, поместил его в свой собственный файл (в моем основном приложении, а не в моей библиотеке Animals). Наличие статического фабричного метода казалось милым и умным, но я понял, что на самом деле он не решает никаких проблем проектирования.
Я понятия не имею, как это относится к идиоматическому C #, так как я часто переключаю языки, я обычно игнорирую идиомы и соглашения, свойственные языкам, и стеки разработчика вне моей обычной работы. Во всяком случае, мой C # может выглядеть "питоническим", если это имеет смысл. Я стремлюсь к общей ясности.
Кроме того, я не знаю, было бы преимущество использования метода статической фабрики в случае небольших, простых классов, которые вряд ли будут расширены в будущей работе - в некоторых случаях было бы неплохо иметь все это в одном исходном файле.
источник