我有一个棘手的建模问题,我想有另一个观点。
我正在处理一个被某些引擎作为一个整体对待的模型。看起来像这样(名称不是我们使用的名称):
public class Container{
// Some other specific properties and methods, ctor etc
public IList<Group> Groups {get; private set;}
// For convenience, we need that
public IList<Element> Elements {get; private set;}
}
public class Group{
// Specific stuff here
public IList<Element> Elements{get; private set;}
public Container Container{get; set;}
}
public class Element{
public Group Group {get; set;}
}
在整个模型中,我们都有那些双重引用,因为模型被引擎视为一个整体。
现在,棘手的部分:我需要创建 2 个特定模型,共享这个组织。
目前,我有一个包含三个类的模型:Container - Group - Element。
我需要创建共享相同结构的特定模型,但在整个模型中都有特定的类。
- BaseContainer、BaseGroup、BaseElement(父级)
- ContainerFoo - GroupFoo - ElementFoo(第一个孩子)
- ContainerBar - GroupBar - ElementBar(第二个孩子)
而且,要完整,最重要的是我需要强类型集合。例如,我需要 ContainerFoo 中的 GroupFoo 列表,而不是父类型的列表。
我探索了两种方法来实现这一点:泛型和创建新属性。
例如:
public class BaseContainer<TGroup, TElement>{
public IList<TGroup> Groups {get; private set;}
public IList<TElement> Elements{get; private set;}
}
public class BaseGroup<TContainer, TElement>{
public TContainer Container {get; set;}
public IList<TElement> Elements {get; private set;}
}
public class BaseElement<TGroup>{
public TGroup Group{get; set;}
}
public class ContainerFoo: BaseContainer<GroupFoo, ElementFoo>{
// Specific stuff here
}
public class GroupFoo: BaseGroup<ContainerFoo, ElementFoo>{
}
public class ElementFoo: BaseElement<ContainerFoo>{
}
此解决方案在这种情况下有效,但:
- 容器中的类型列表可以很长,因为容器实际上是整个模型的入口点(这里简化了)
- 我们实际上不能将它与用于序列化和反序列化的 protobuf-net 一起使用。
第二种解决方案:
public abstract class BaseContainer{
public abstract IList<BaseGroup> Groups {get;}
public abstract IList<BaseElement> Elements{get;}
}
public abstract class BaseGroup{
public abstract BaseContainer Container {get; set;}
}
public abstract class BaseElement{
public abstract BaseGroup Group{get; set;}
}
public ContainerFoo : BaseContainer{
public override IList<BaseGroup> Groups {
get{
// We are using .Net 4, and we can do that.
return (IList<BaseGroup>)this.GroupsFoo;
}
}
public IList<GroupFoo> GroupsFoo{ get; private set;}
// Same thing for elements
}
// You see the point, I don't want to create other classes here.
我认为您显然可以看到我不喜欢第二种解决方案的地方!
还有什么想法吗?