我无法发布图片,但我正在使用此模型制作文档工具。
我有对象(抽象)类和关系类和属性类。
所有这些都挂在上下文类中,我保留了环境变量,还有一个对象集合,一个属性集合和一个关系集合。
让对象从上下文继承是一个好主意吗?所以我可以将所有内置的功能和行为继承到所有对象和关系?
或者更好的做法是将它分开并创建一个基类(行为),其中上下文,对象,属性和关系将继承我想要流经对象的所有功能,并保留一组属性这个更高层(行为)可以扩展所有对象并根据需要添加属性吗?
我希望它足够清楚......发布图表会更容易,但我还不能。
这里有一个小伪代码来表明我的意思:
public abstract class Behaviour
{
ToXML();
JSonSerilize();
Save();
Display();
Compare();
}
public abstract class Context : Behaviour
{
public List<Object> Objects { get; set; }
public List<Property> Properties { get; set; }
public List<Relationship> Relationships { get; set; }
AddObject();
}
public class Property : Context
{
public Object ObjectRelated { get; set; }
}
public abstract class Object : Context
{
}
public abstract class Relationship : Context
{
public Object Source { get; set; }
public Object Target { get; set; }
}
OR
public abstract class Behaviour
{
ToXML();
JSonSerilize();
Save();
Display();
Compare();
public List<Property> Properties { get; set; }
}
public abstract class Context : Behaviour
{
public List<Object> Objects { get; set; }
public List<Relationship> Relationships { get; set; }
AddProperty (Object, value) { base:Properties.Add}
}
public class Property : Behaviour
{
public Object ObjectRelated { get; set; }
}
public abstract class Object : Behaviour
{
AddProperty (Object, value) { base:Properties.Add}
}
public abstract class Relationship : Behaviour
{
public Object Source { get; set; }
public Object Target { get; set; }
AddProperty (Object, value) { base:Properties.Add}
}
我非常喜欢第二种设计,其中所有对象(对象,关系,上下文)都可以在属性中进行扩展,但我不喜欢这样的事实:我必须将属性集合保留在上层类中(行为) ),似乎太紧密耦合了。 任何想法,利弊?
进一步详情:(谢谢NWard)
目标:用于记录工具的核心库。 我想要一个通用的核心库,我可以用它来实现不同的文档场景。 我希望分离这些对象如何在内存中保持,序列化和操作以及它的实际扩展/实现(2层)
要求: 我需要能够通过web服务/ odata / db / json持久/传输整个&#34;数据上下文类&#34;及其所有对象+属性及其关系。
即使应用程序中的每个类都需要动态生成 生成属性列表(为什么?)
因为我想生成一个核心对象类型,还有一个关系类型和一个数据上下文类型,能够在不改变其基础&#34;结构的情况下进行扩展。
实施示例如下:
public class FancyRectangle : Object
{
public string Name { get { return this.GetPropertyValueString("Name"); } set { this.AddProperty("Name", value); } }
public string Description { get { return this.GetPropertyValueString("Description"); } set { this.AddProperty("Description", value); } }
public float Height { get { return this.GetPropertyFloat("Height"); } set { this.AddProperty("Height", value); } }
public float Lenght { get { return this.GetPropertyFloat("Lenght"); } set { this.AddProperty("Lenght", value); } }
}
当然,所有这些对象都可以执行以下操作:
FancyRectangle rect1 = new FancyRectangle();
rect1.AddRelationship(rect2);
rect1.ToXml();
rect2.ToJson();
另外
我想在抽象类中实现这些行为,所以当Object类被实现时(即FancyRectangle类)我不必将这些常见的行为和属性编码到其中,这些行为和属性都是我想要的继承.ToXml(),. ToJson()
的一个实现我希望这个核心库非常便于携带,并且可以轻松扩展,并且不会限制其实现。
此核心库可能会与读者,用户界面和演示者进行交互。
干杯
答案 0 :(得分:2)
我发现你的继承结构很难理解。也许你理解其背后的动机对你更有意义,但是通过继承的面向对象模式通常通过 他们的超类来完成。属性,关系,上下文和对象是否真的是相同的 - 行为?我倾向于认为他们不是。但是,如果您有关于特定案例的更多具体细节,那将非常有用。
在进行面向对象设计时要记住的一组好的启发式算法是SOLID(http://en.wikipedia.org/wiki/SOLID_(object-oriented_design))。
由于您的继承结构非常广泛,您的设计未能通过单一责任原则和接口(抽象类)隔离原则。您的对象负责序列化自己,比较自己,保存自己和显示自己。这是很多责任!对于其他类来说,处理显示,数据持久性,比较等事情会更好 - 让对象保持其状态并且不了解应用程序的其他问题。这样,您可以更改 这些问题的实施方式,但您的对象不受影响。这使您的应用程序更清晰,更易于维护。
我会在这里考虑你的结构提出一种不同的方法。您希望使您的界面更小,更集中。即使你的应用程序中的每个类都需要一个动态生成的Properties
列表(为什么?),这应该是一个非常低级的接口,也许是IPropertyHaving
,所有其他接口都从这个接口继承 - 但没有任何其他功能。通过保持接口小,您不必担心这种紧密耦合的设计。但是,我建议所有应用程序类不太可能需要维护自己的属性列表。在任何情况下:
//Or abstract classes, depending on which makes more sense
interface IPropertyHaving
{
List<IProperty> Properties { get; }
void Add(Property property);
//etc.
}
请注意,Properties属性是get-only,因为您不太可能希望接口的使用者能够完全替换属性列表。您的对象接口可以继承此属性,但定义特定于对象的功能。
interface IObject : IPropertyHaving
{
string ToXml();
string ToJson();
//Shared object properties
}
这些对象维护自己的数据/状态。他们知道如何序列化自己,并且他们有属性,但这都是。
您希望拥有一个“联系在一起”的界面或类别。您的应用程序功能 - 上下文的想法很好。
interface IDataContext : IPropertyHaving //?
{
List<IObject> Objects { get; }
void Save(IObject entity);
IRelationshipManager RelationshipManager { get; }
IObjectComparer ObjectComparer { get; }
//Collection manipulation functions, etc.
}
现在,您的数据上下文仅负责维护您的IObject集合以及保存/检索/等。这使您的对象免于CRUD自己的责任。通过使用接口,您可以根据应用程序要求切换特定于案例的实现。请注意,您的上下文仅直接负责维护整个应用程序的状态 - 它具有您的对象集合,但它将大部分其他功能委托给单独的接口,这些接口组成了上下文。
同样,您可以定义一个IObjectComparer
接口,该接口只有一个方法Compare(IObject first, IObject second)
。然后,您的上下文可以包含IObjectComparer。这意味着虽然您的上下文能够比较对象,但您可以交换或修改 对象的比较方式,而不会影响任何其他代码。
您还可以拥有一个跟踪,创建或检索关系的IRelationshipManager
类。同样,这可以在您的上下文中绑定在一起。然后,您的应用程序可以维护单个IContext
,以及IDisplayManager
或其他东西(这可能是您的GUI框架的一部分 - 这是WPF吗?),它知道如何将对象写入屏幕
有关您具体案例的更多详细信息,我们将能够提供更好的建议。