У меня есть (растущий) список Data-Generators. Генератор, который мне нужен, создается фабричным классом. Генераторы реализуют общий интерфейс, который включает, помимо прочего, статическую строку name
.Factory Pattern, выбрав по свойству
Что мне нужно сделать: вызвать метод factory.Create со строковым параметром для вышеупомянутого имени. Метод create находит генератор с этим именем и возвращает новый экземпляр указанного генератора.
Бонус, на мой взгляд, для этого: мне нужно только добавить новые классы генераторов без необходимости редактировать завод.
Вопрос:
- Это хороший способ справиться с этой проблемой?
- Как я могу найти все генераторы? Отражение по каждой реализации интерфейса/каждого члена пространства имен (уникальное для генераторов + их интерфейс)?
- Правильно ли назвать этот способ работы на заводе или это какой-то другой шаблон?
В конце концов, я бы назвал завод, как это (упрощенный):
//Caller
public DataModel GetData2()
{
var generator = new DataFactory().Create("Gen.2");
return generator.GetData();
}
//Factory
public class DataFactory
{
public AbstractDataGenerator Create(string type)
{
//Here the magic happens to find all implementations of IDataGenerator
var allGenerators = GetImplementations();
var generator = allGenerators.FirstOrDefault(f => f.name == type);
if (generator != null)
return (AbstractDataGenerator)Activator.CreateInstance(generator);
else
return null;
}
}
//Interface
public abstract class AbstractDataGenerator
{
public static string name;
public abstract DataModel GetData();
}
//Data-Generators
public class DataGen1 : AbstractDataGenerator
{
public static string name = "Gen.1";
public DataModel GetData()
{
return new DataModel("1");
}
}
public class DataGen2 : AbstractDataGenerator
{
public static string name = "Gen.2";
public DataModel GetData()
{
return new DataModel("2");
}
}
Если на заводе магия GetImplementations()
быть сделано с помощью отражения или как-то другое? Должен ли я использовать совершенно другой подход?
Поскольку ответы относятся к IoC и DI: этот проект уже использует NInject, поэтому он будет доступен. Переключен от интерфейса к абстрактному классу.
Один вопрос, который я нашел такого подхода заключается в том, что для того, чтобы получить свойство «Name» генератора вы _need экземпляр object_. – stuartd
Вот почему я сделал свойство статическим. Это должно устранить необходимость в экземпляре, если я не ошибаюсь. – MilConDoin
Интерфейсы не могут содержать статические элементы. – stuartd