[英]FactoryPattern with derived generic classes
这是一个简短的片段,直截了当,我隐藏了不相关的细节。 目标是让我的工厂使用我的 generics 设计类型。 在帖子的最后,我有两个观察。
界面
public interface IWorker<T> where T : IWorkload
{
T CraftWorkload(string plainWorkload);
Task DoWork(T workload);
}
工作负载
public interface IWorkload
{
// some properties
}
底座 class
internal abstract class Worker<T> : IWorker<T> where T : IWorkload
{
public T CraftWorkload(string workAsJsonString)
{
return JsonConvert.DeserializeObject<T>(workAsJsonString, new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Error
});
}
public abstract Task DoWork(T workload);
}
另派生基地class
internal abstract class RestWorker<T> : Worker<T> where T : IWorkload
{
// this is a worker that interact with http requests
}
混凝土工人
internal class WorkerA: RestWorker<WorkerA_Workload>
{
public override Task DoWork(WorkerA_Workload workload)
{
}
}
internal abstract class WorkerB: Worker<WorkerB_Workload>
{
public override Task DoWork(WorkerB_Workload workload)
{
}
}
工人工厂
MessageType
是一个枚举,用于标识具有类型的工作人员
internal interface IWorkerFactory
{
IWorker<IWorkload> GetWorker(MessageType type);
}
internal class WorkerFactory : IWorkerFactory
{
public IWorker<IWorkload> GetWorker(MessageType type)
{
switch (type)
{
case MessageType.WorkerA:
return new WorkerA() as IWorker<IWorkload>;
case MessageType.WorkerB:
return new WorkerB() as IWorker<IWorkload>;
.
.
.
.
.
default:
throw new ArgumentException("The type must be a type that maps to an available worker");
}
}
}
两个观察:
IWorker<IWorkload>
它会感到困惑我的 inheritance 有意义吗?
您的IWorker<T>
接口表示一个工作者,它既能够生成T
类型的对象,又能够使用T
类型的对象(因为它使用T
作为方法的参数和方法的返回类型)。 这意味着IWorker<IWorkload>
是一个 object ,它能够生成IWorkload
类型的对象, WorkerA
和WorkerB
可以这样做,因为它们生成的WorkerA_Workload
和WorkerB_Workload
对象是IWorkload
对象。 但这也意味着IWorker<IWorkload>
需要能够接受 *any IWorkload
并对其进行处理。 WorkerA
和WorkerB
都无法做到这一点。 他们只能分别接受WorkerA_Workload
和WorkerB_Workload
输入,但为了实现IWorker<IWorkload>
的接口,他们需要能够接受任何其他类型的工作负载。
如果您的工作人员实际上可以接受任何IWorkload
,并且他们实际上不需要接受特定类型的工作负载,那么您需要调整您的代码以基本上删除所有受 IWorkload 约束的泛型类型,而只使用非泛型IWorkload
类型在所有这些地方。 (您还需要使IWorker<T>
相对于T
协变。)
如果您的工人实际上不能接受任何IWorkload
并且需要特定类型的工作负载,那么您不能将所有工人视为IWorker<IWorkload>
,您需要始终将它们视为IWorker<T>
其中 T是他们可以接受的实际特定工作负载类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.