通用接口的工厂模式
Factory pattern from generic interface
我有通用接口 IProcessor<T, TU>
和它的 2 个实现:
StandartDocumentProcessor
和 ModDocuemntProcessor
.
我将使用工厂模式(或类似的东西)来实例化变量 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>
一些特定的 class。
????? currentProcessor = Factory.Create(input_argument_which_allows_to_define_concrete_implementation_of_IProcessor)
无所谓,在这里展示Create
方法的实现。我想问一下 返回 Create
方法的类型 。
因为 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
方法,因为它不适合此模式。如果您仍然需要它,请将其移至另一个界面。 ProcessResult
是 class 的基础/XmlDocument
的接口。
另请注意:如果您根本不使用泛型并使用继承/基础 classes,一切都会更简单。 工厂模式通常用于隐藏和封装实现细节和类型,包括一些通用参数。如果你想从你的代码中获取类型信息工厂,也许使用工厂不是最好的主意。
我有通用接口 IProcessor<T, TU>
和它的 2 个实现:
StandartDocumentProcessor
和 ModDocuemntProcessor
.
我将使用工厂模式(或类似的东西)来实例化变量 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>
一些特定的 class。
????? currentProcessor = Factory.Create(input_argument_which_allows_to_define_concrete_implementation_of_IProcessor)
无所谓,在这里展示Create
方法的实现。我想问一下 返回 Create
方法的类型 。
因为 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
方法,因为它不适合此模式。如果您仍然需要它,请将其移至另一个界面。 ProcessResult
是 class 的基础/XmlDocument
的接口。
另请注意:如果您根本不使用泛型并使用继承/基础 classes,一切都会更简单。 工厂模式通常用于隐藏和封装实现细节和类型,包括一些通用参数。如果你想从你的代码中获取类型信息工厂,也许使用工厂不是最好的主意。