我有一个通用界面:
public interface IReader<T> where T: Result
{
IEnumerable<T> ReadResults();
}
其中Result
是基类,并扩展为DetailedResult
:
public class Result
{
// ...
}
public class DetailedResult : Result
{
// ... ...
}
现在我有两个IReader
的具体类型,每个实现返回不同的类型,特定于读者类型:
public class DefaultResultReader<Result> : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader<DetailedResult> : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
上面介绍的结构使用泛型。如果可能的话我想摆脱它,并且有一些工厂可以为我创建IReader
的具体实现 - DefaultResultReader.ReadResults()
方法必须返回Result
而{{1}必须返回DetailedResultReader.ReadResults()
我的问题是抽象工厂应该如何寻找这个结构 - 如何设计它以便我可以按要求创建特定的DetailedResult
对象?
答案 0 :(得分:2)
如果DefaultResultReader<Result>
将始终返回IEnumerable<Result>
,并且DetailedResultReader<DetailedResult>
将始终返回IEnumerable<DetailedResult>
,我建议您制作课程
public class DefaultResultReader : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
然后你有了抽象工厂类
public class ReaderFactory
{
public IReader<Result> CreateDefaultResultReader()
{
return new DefaultResultReader();
}
public IReader<DetailedResult> CreateDetailedResultReader()
{
return new DetailedResultReader();
}
}
答案 1 :(得分:2)
我没有得到你想要的东西,但我想你期待以下内容:
public interface IReader<T> where T : Result
{
IEnumerable<T> ReadResults();
}
public class Result
{
}
public class DetailedResult : Result
{
// ... ...
}
public class DefaultResultReader : IReader<Result>
{
public IEnumerable<Result> ReadResults()
{
return null;
}
}
public class DetailedResultReader : IReader<DetailedResult>
{
public IEnumerable<DetailedResult> ReadResults()
{
return null;
}
}
public abstract class ResultReaderAbsractFactory
{
public abstract IReader<Result> CreareDefaultResultReader();
public abstract IReader<DetailedResult> CreareDetailedResultReader();
}
public class ConcreteResultRaderFactory : ResultReaderAbsractFactory
{
public override IReader<Result> CreareDefaultResultReader()
{
return new DefaultResultReader();
}
public override IReader<DetailedResult> CreareDetailedResultReader()
{
return new DetailedResultReader();
}
}
答案 2 :(得分:1)
如果您想使其完全通用,则意味着即使您创建新的阅读器类型,也不必扩展此类。你可以简单地做这样的事情:
public static class ResultReaderFactory
{
public static IEnumerable<T> ReadResults<T>() where T : Result
{
IReader<T> reader = GetReader<T>();
if(reader != null)
{
return reader.ReadResults();
}
return null;
}
public static IReader<T> GetReader<T>() where T : Result
{
// get the first reader implementation from the list
// that matches the generic definition
IReader<T> reader = _instances
.FirstOrDefault(
r => r.GetType()
.GetInterfaces()
.Any(
i => i == typeof(IReader<T>)
)
) as IReader<T>;
return reader;
}
// placeholder for all objects that implement IReader
static IEnumerable<object> _instances;
static ResultReaderFactory()
{
// register all instances of classes,
// that implements IReader interface
_instances = typeof(ResultReaderFactory)
.Assembly
.GetTypes()
.Where(
t => t.GetInterfaces()
.Any(
i => i.Name
.StartsWith("IReader`1")
)
)
.Select(t => Activator.CreateInstance(t));
}
}
要使用此功能,您只需在IReader<T>
所在的同一个程序集中创建实现ResultReaderFactory
的类。然后你可以忘记那个工厂对象,只需随时调用它:
ResultReaderFactory.GetReader<DetailedResult>();
// or assuming you've created class ExtremalyDetailedResult
// and ExtremalyDetailedResultReader
ResultReaderFactory.GetReader<ExtremalyDetailedResult>();
每当您启动应用程序时,这将读取实现IReader<T>
的所有类型。然后它会将所有这些类(已经实例化)打包到List<object>
中,以便稍后使用它们。这确实很慢,因为它使用反射和Linq来确定返回哪个IReader<T>
实现。