繁体   English   中英

FactoryPattern 与派生的泛型类

[英]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");
        }
    }
}

两个观察:

  1. 如果我将工厂更改为返回而不隐式转换为IWorker<IWorkload>它会感到困惑
  2. 如果我投(如代码所示)它返回 null

我的 inheritance 有意义吗?

您的IWorker<T>接口表示一个工作者,它既能够生成T类型的对象,能够使用T类型的对象(因为它使用T作为方法的参数和方法的返回类型)。 这意味着IWorker<IWorkload>是一个 object ,它能够生成IWorkload类型的对象, WorkerAWorkerB可以这样做,因为它们生成的WorkerA_WorkloadWorkerB_Workload对象是IWorkload对象。 但这也意味着IWorker<IWorkload>需要能够接受 *any IWorkload并对其进行处理。 WorkerAWorkerB都无法做到这一点。 他们只能分别接受WorkerA_WorkloadWorkerB_Workload输入,但为了实现IWorker<IWorkload>的接口,他们需要能够接受任何其他类型的工作负载

如果您的工作人员实际上可以接受任何IWorkload ,并且他们实际上不需要接受特定类型的工作负载,那么您需要调整您的代码以基本上删除所有受 IWorkload 约束的泛型类型,而只使用非泛型IWorkload类型在所有这些地方。 (您还需要使IWorker<T>相对于T协变。)

如果您的工人实际上不能接受任何IWorkload并且需要特定类型的工作负载,那么您不能将所有工人视为IWorker<IWorkload> ,您需要始终将它们视为IWorker<T>其中 T是他们可以接受的实际特定工作负载类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM