У меня есть система, которая выполняет операции с большим количеством Things
, их можно считать аппаратными устройствами, доступными по каналу связи.
Я использую конструкцию менеджера, которая принимает задачи для одного Things
. Теперь существует как минимум три типа Thing
, и с ними связаны немного другие свойства. Менеджер должен знать об этих дополнительных свойствах, так как они необходимы для правильного выполнения любой операции (некоторые Things
должны иметь свои X foo'd вместо своих Y и т. Д ...).
На данный момент у меня есть отдельный класс менеджера для каждого типа вещей. Это вызывает многократное дублирование, поскольку Things
в основном похожи.
Было бы хорошо, если бы у меня был абстрактный менеджер, который реализует большую часть функциональности, и тогда каждая конкретная реализация может предоставить небольшие дополнительные биты.
Вот очень упрощенный пример:
public abstract class ThingManager
{
private ConcurrentDictionary<Guid, ??ThingTask??> _ThingTaskQueue;
public virtual AddNewThingTask(<params>)
{
??ThingTask?? NewTask = new ??ThingTask??(<params>);
_ThingTaskQueue.Add(NewTask);
Monitor.Pulse(_NewDataToProcess);
}
/* Implemented by the concrete, will depend on the type of ??ThingTask?? */
public abstract GetSomeTaskParameterForAThing(Guid thingID)
}
public class ThingTask
{
public enum ThingOperation
{
Foo,
Bar
};
public String Name { get; set; };
public ThingType Type { get; set; };
public ThingOperation Operation { get; set; }
}
public class AdvancedThingTask
{
public enum ThingOperation
{
Foo,
Bar,
Baz
};
public String Name { get; set; };
public ThingType Type { get; set; };
public ThingOperation Operation { get; set; }
public Boolean EnableFrobber { get; set; }
}
Как видите, мне нужен какой-то способ, при определении бетона ThingManager
, чтобы ??ThingTask??
был либо ThingTask
, либо AdvancedThingTask
. Тогда бы было конкретное использование дополнительных свойств при реализации абстрактных методов.
Использование интерфейса для ??ThingTask??
не сработает, потому что свойства должны быть объявлены в интерфейсе, и у каждого есть разные доступные свойства.
У меня такое чувство, что я упускаю что-то очень очевидное в том, как сделать это чисто, надеюсь, кто-то может помочь:)