可能清楚的一点是你的设计有些缺陷。在通用方法中,打开类型并不是最好的做法,因为它违背了它的目的。但是不清楚的是您的课程的目的是什么。
一些猜测:
1) 看到你的配对类AskItem 和AskTankTruckAggregate<T> 等我不认为后者必须是一个通用类,它是一个非常具体的类,与AskItem 紧密耦合。我会像这样重新设计它
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem
{
//use reflection to find the type that inherits AbstractAggregate<T>
//instantiate the type
//cast to AbstractAggregate<T> and return
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
这样称呼:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
2) 另一种方式:将聚合创建作业委托给您的 ListItems。
public abstract class ListItem //or interface
{
protected abstract object Create();
}
public class AskItem : ListItem { //implement to return AskTankTruckAggregate
}
public class BlogItem : ListItem { //implement to return TankTruckBlogAggregate
}
public class ResourceItem : ListItem { //implement to return ResourcesAggregate
}
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem, new()
{
return (AbstractAggregate<T>)new T().Create();
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
这样称呼:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
3) 或相同,但使用泛型使其类型更强:
public abstract class ListItem<T> where T : ListItem<T> //or interface
{
protected abstract AbstractAggregate<T> Create();
}
public class AskItem : ListItem<AskItem> { //implement to return AskTankTruckAggregate
}
public class BlogItem : ListItem<BlogItem> { //implement to return TankTruckBlogAggregate
}
public class ResourceItem : ListItem<ResourceItem> { //implement to return ResourcesAggregate
}
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem, new()
{
return new T().Create();
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
这样称呼:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
4) 最后,可能会使返回类型不那么通用吗?涉及switch case,我不喜欢。
public enum AggregateTypes { TankTruckBlog, AskTankTruck, Resources }
public static class AbstractAggregateFactory
{
public static AbstractAggregate GetAggregateClient(AggregateTypes type)
{
switch (type)
{
case AggregateTypes.AskTankTruck:
return new AskTankTruckAggregate<AskItem>();
case AggregateTypes.TankTruckBlog:
return new TankTruckBlogAggregate<BlogItem>();
case AggregateTypes.Resources:
return new ResourcesAggregate<ResourceItem>();
default:
throw new AggregateDoesNotExistException();
}
}
}
public abstract class AbstractAggregate
{
}
public abstract class AbstractAggregate<T> : AbstractAggregate
{
}
//or change the definition to AskTankTruckAggregate : AbstractAggregate<AskItem>
public class AskTankTruckAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
//or change the definition to TankTruckBlogAggregate : AbstractAggregate<BlogItem>
public class TankTruckBlogAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
//or change the definition to ResourcesAggregate : AbstractAggregate<ResourceItem>
public class ResourcesAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
这样称呼:
AbstractAggregateFactory.GetAggregateClient(AggregateTypes.AskTankTruck); //etc
Imo,这种方法比反射方法更糟糕。以后很容易忘记一些枚举检查。
总而言之,3rd 在我看来是最好的,但在不知道你的设计目标的情况下,它很难预测。几点建议:
您的工厂名称听起来更像AggregateFactory。其中的“抽象”使它更多地关注实现。
如果你需要一个枚举来表示类型,不要让它嵌套。嵌套的公共类型更难调用。取出包装静态类(如我的第 5 种方法)。
将您的基类重命名为Aggregate<T> 或AggregateBase<T>。再次,它中的“抽象”使它更多地与实现有关,完全没有必要。