Справочная информация
У меня есть набор интерфейсов / классов следующим образом. Для простоты представьте больше свойств, коллекций и т. Д. c.
interface IMaster
{
//Some properties
}
interface IB : IMaster
{
string PropOnA { get; set }
}
interface IC : IMaster
{
string PropOnB { get; set }
}
class B : IB
class C : IC
...
Эти контракты были разработаны для хранения данных (которые в каждом конкретном случае хранятся в несколько ином формате). Существует много кода, который использует эти контракты для получения, форматирования, обработки, записи и т. Д. c. Мы разработали целую библиотеку, которая не видит конкретные реализации (B, C) любого из этих контрактов, инвертируя управление и позволяя пользователю использовать наши «реализации по умолчанию» для каждого контракта или просто загружая их самостоятельно. У нас есть реестр, в котором пользователь может зарегистрировать другую реализацию.
С этой целью я реализовал своего рода шаблон стратегии, в котором существует стратегия для каждого типа контракта, основанная на выполняемой задаче. Для простоты, скажем, задача состоит в том, чтобы написать , в действительности это намного сложнее.
interface IWriteStrategy
{
public Write(IMaster thing);
}
class WriterA : IWriteStrategy
class WriterB : IWriteStrategy
etc
Вышеупомянутые конкретные стратегии также никогда не "видны" в нашей библиотеке, Клиент должен зарегистрировать свою собственную реализацию или нашу версию по умолчанию.
Недостаток дизайна ??
Мне не нравятся актеры в каждой стратегии, которая сейчас необходима.
public classWriterA : IWriteStrategy
{
public void Write(IMaster thing)
{
if(thing is IA thingA)
//do some work
}
}
public classWriterB : IWriteStrategy
{
public void Write(IMaster thing)
{
if(thing is IB thingB)
//do some work
}
}
То, что мы хотим сделать, это иметь возможность oop через список IMaster
объектов и выполнение некоторых операций.
foreach(var thing in Things)
{
var strategy = GetStrategy(thing.GetType()); //this gets the strategy object from our `registry` if one exists
strategy.Execute(thing);
}
Приведенная выше схема позволяет это сделать, но, похоже, есть недостаток, который я не могу найти в жизни для меня. Мы должны привести к указанному c интерфейсу в каждой реализации стратегии.
Я пробовал с дженериками, но, похоже, просто не могу это прибить.
Вопрос
Какой лучший способ придумать это, чтобы избежать броска, но все же быть в состоянии l oop через список IMaster
вещей и относиться к ним одинаково? Или здесь абсолютно необходим актерский состав?
Я пытаюсь следовать дизайну SOLID, но чувствую, что актерский состав портится с этим, поскольку клиент, реализующий стратегии, должен будет выполнить актерский состав, чтобы получить что-либо для работать по методу Write
.
[Edit] Я обновил классы, реализующие IWriteStrategy
.