通用界面的工厂模式

时间:2017-08-16 16:11:33

标签: c# .net clr

我有通用接口IProcessor<T, TU>和2个实现:

StandartDocumentProcessorModDocuemntProcessor

我将使用Factory模式(或类似的smth)来实例化变量 currentProcessor

IProcessor<T, TU> currentProcessor = Factory.Create(argument)

然后,我将调用方法currentProcessor.ProcessFrom()currentProcessor.ProcessTo()

第一个问题:对于currentProcessor来说,IProcessor<T,TU>IProcessor类型是不可能的,因为CLR不允许这样做并且坚持要具体输入我的变量。

第二个问题:我浏览了互联网,发现了 Reflection Activator.CreateInstance()的丑陋解决方案,这些解决方案在降低性能方面存在熟悉的问题。

请建议,是否可以避免:反思,投射到object或使用dynamic

UPD IProcessor.cs

public interface IProcessor<T, TU> where T : DocumentValidation
    {
        HtmlContent RetrieveDocument(SearchItem item);

        bool ValidateObject(T obj);

        T ProcessFrom(HtmlContent content);

        TU ProcessTo(T source);

        bool SaveTo(TU target, T source);

    } 

首次实施IProcessor - StandardDocumentProcessor.cs

class StandardDocumentProcessor : IProcessor<Document, XmlDocument>
    {
        public HtmlContent RetrieveDocument(SearchItem item)
        {
            throw new NotImplementedException();
        }

        public bool ValidateObject(Document obj)
        {
            throw new NotImplementedException();
        }

        public Document ProcessFrom(HtmlContent content)
        {
            throw new NotImplementedException();
        }

        public XmlDocument ProcessTo(Document source)
        {
            throw new NotImplementedException();
        }

        public bool SaveTo(XmlDocument target, Document source)
        {
            throw new NotImplementedException();
        }
    }

IProcessor的第二次实施 - ModDocumentProcessor.cs

public class ModDocumentProcessor : IProcessor<ModDocument, XmlDocument>
    {
        public HtmlContent RetrieveDocument(SearchItem item)
        {
            throw new NotImplementedException();
        }

        public bool ValidateObject(ModDocument obj)
        {
            throw new NotImplementedException();
        }

        public ModDocument ProcessFrom(HtmlContent content)
        {
            throw new NotImplementedException();
        }

        public XmlDocument ProcessTo(ModDocument source)
        {
            throw new NotImplementedException();
        }

        public bool SaveTo(XmlDocument target, ModDocument source)
        {
            throw new NotImplementedException();
        }
    }

现在我要创建工厂模式以使用某个特定类来实例化IProcessor<T, TU>

????? currentProcessor = Factory.Create(input_argument_which_allows_to_define_concrete_implementation_of_IProcessor)

无论在这里显示Create方法的实现,都是如此。我很好地询问返回Create方法的类型

1 个答案:

答案 0 :(得分:1)

C# 4.0开始,您可以简单地将工厂方法声明为动态方法,它将起作用:

public static dynamic Create(string at) {
   if (condition)
     return new StandardDocumentProcessor();
   else
     return new ModDocumentProcessor();
}

调用:

dynamic m = Create("mod");

当然,这就像作弊一样,因为使用dynamic你会失去类型安全性(冒运行时异常的风险)并且会降低性能。

如果您对自己的应用领域一无所知,但如果您方可导入此方面,我会更改一些内容并尝试通用的out参数。

public interface IProcessor<out T, out TU> where T : DocumentValidation {
    HtmlContent RetrieveDocument(SearchItem item);
    bool ValidateObject(DocumentValidation obj);
    T ProcessFrom(HtmlContent content);
    TU ProcessTo(DocumentValidation source);
}

厂:

public static IProcessor<DocumentValidation, ProcessResult> Create(string at) {
  if (condition(at))
    return new StandardDocumentProcessor();
  else
    return new ModDocumentProcessor();
  }

请注意,我删除了SaveTo方法,因为它不适合此模式。如果您需要它,请将其移动到另一个界面。 ProcessResultXmlDocument的基类/接口。

另一个注意事项:如果您根本不使用泛型并使用继承/基类,一切都会更简单。 工厂模式通常用于隐藏和封装实现细节和类型,包括一些通用参数。如果您想从工厂中获取类型信息,也许它不是'最好的想法是使用工厂。