1
我有一個棘手的建模問題,我想在這個問題上有另一個觀點。使用強類型的模型繼承
我正在處理一個模型,它被一些引擎視爲一個整體。它看起來像(名字是我們使用的不是):
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個特定的模型,共享這個組織。
目前,我有三個類的模型:容器 - 組 - 元素。
我需要創建共享相同結構的特定模型,但是在模型中使用特定的類。
- 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.
我想你可以很明顯的看出什麼,我不喜歡這個第二個解決方案!
還有什麼想法?
謝謝。新的修改器可能很有用。我會檢查出來的。不需要在每次訪問時創建一個新的列表實例,似乎我可以轉換它。 – ghusse
關於接口,我有一些需要在基類中實現的常見行爲。 – ghusse
根據您常見行爲的複雜性,可能會將其分爲另一類。我嘗試在可能的情況下使用接口和組合而不是繼承。如果你發現你在不同的時間需要不同的行爲(比如Foo和Bar使用行爲A而Baz使用行爲B),那麼你可以使用策略而不是日益複雜的繼承層次結構。 –