抽象工厂模式而不是泛型——怎么样?
Abstract factory pattern instead of generics - how?
我有一个通用接口:
public interface IReader<T> where T: Result
{
IEnumerable<T> ReadResults();
}
其中 Result
是基数 class 并扩展为 DetailedResult
:
public class Result
{
// ...
}
public class DetailedResult : Result
{
// ... ...
}
现在我有两个 IReader
的具体类型,每个实现 returns 不同的类型,特定于 reader 类型:
public class DefaultResultReader<Result> : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader<DetailedResult> : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
上面给出的结构使用了泛型。如果可能的话,我想摆脱它,并有某种工厂可以为我创建 IReader
的具体实现 - DefaultResultReader.ReadResults()
方法必须 return Result
而 DetailedResultReader.ReadResults()
必须 return DetailedResult
我的问题是抽象工厂应该如何寻找这个结构——如何设计它以便我可以根据要求创建特定的 IReader
对象?
如果 DefaultResultReader<Result>
总是 return IEnumerable<Result>
,而 DetailedResultReader<DetailedResult>
总是 return IEnumerable<DetailedResult>
,我建议制作 classes
public class DefaultResultReader : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
然后你就有了抽象工厂class
public class ReaderFactory
{
public IReader<Result> CreateDefaultResultReader()
{
return new DefaultResultReader();
}
public IReader<DetailedResult> CreateDetailedResultReader()
{
return new DetailedResultReader();
}
}
我没有得到你想要的,但我猜你期待以下内容:
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();
}
}
如果你想让它完全通用,这意味着你不必扩展这个 class 即使你创建新的 reader 类型。你可以简单地做这样的事情:
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));
}
}
要使用它,您只需在 ResultReaderFactory
所在的同一程序集中创建实现 IReader<T>
的 classes。然后你就可以忘记那个工厂对象,只要你想调用它就可以了:
ResultReaderFactory.GetReader<DetailedResult>();
// or assuming you've created class ExtremalyDetailedResult
// and ExtremalyDetailedResultReader
ResultReaderFactory.GetReader<ExtremalyDetailedResult>();
这将在您启动应用程序时读取所有实现 IReader<T>
的类型。然后它将所有这些 classes(已经实例化)打包到 List<object>
中,以便您稍后可以使用它们。这真的很慢,因为它使用反射和 Linq 来确定哪个 IReader<T>
实现到 return。
我有一个通用接口:
public interface IReader<T> where T: Result
{
IEnumerable<T> ReadResults();
}
其中 Result
是基数 class 并扩展为 DetailedResult
:
public class Result
{
// ...
}
public class DetailedResult : Result
{
// ... ...
}
现在我有两个 IReader
的具体类型,每个实现 returns 不同的类型,特定于 reader 类型:
public class DefaultResultReader<Result> : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader<DetailedResult> : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
上面给出的结构使用了泛型。如果可能的话,我想摆脱它,并有某种工厂可以为我创建 IReader
的具体实现 - DefaultResultReader.ReadResults()
方法必须 return Result
而 DetailedResultReader.ReadResults()
必须 return DetailedResult
我的问题是抽象工厂应该如何寻找这个结构——如何设计它以便我可以根据要求创建特定的 IReader
对象?
如果 DefaultResultReader<Result>
总是 return IEnumerable<Result>
,而 DetailedResultReader<DetailedResult>
总是 return IEnumerable<DetailedResult>
,我建议制作 classes
public class DefaultResultReader : IReader<Result>
{
IEnumerable<Result> ReadResults();
}
和
public class DetailedResultReader : IReader<DetailedResult>
{
IEnumerable<DetailedResult> ReadResults();
}
然后你就有了抽象工厂class
public class ReaderFactory
{
public IReader<Result> CreateDefaultResultReader()
{
return new DefaultResultReader();
}
public IReader<DetailedResult> CreateDetailedResultReader()
{
return new DetailedResultReader();
}
}
我没有得到你想要的,但我猜你期待以下内容:
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();
}
}
如果你想让它完全通用,这意味着你不必扩展这个 class 即使你创建新的 reader 类型。你可以简单地做这样的事情:
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));
}
}
要使用它,您只需在 ResultReaderFactory
所在的同一程序集中创建实现 IReader<T>
的 classes。然后你就可以忘记那个工厂对象,只要你想调用它就可以了:
ResultReaderFactory.GetReader<DetailedResult>();
// or assuming you've created class ExtremalyDetailedResult
// and ExtremalyDetailedResultReader
ResultReaderFactory.GetReader<ExtremalyDetailedResult>();
这将在您启动应用程序时读取所有实现 IReader<T>
的类型。然后它将所有这些 classes(已经实例化)打包到 List<object>
中,以便您稍后可以使用它们。这真的很慢,因为它使用反射和 Linq 来确定哪个 IReader<T>
实现到 return。