对象实例的动态属性?

时间:2009-02-01 10:15:04

标签: object dynamic model properties

在上一个问题“对象模型设计中有哪些重要规则”之后,现在我想问一下:

有没有办法为类实例提供动态属性?

假设我们有这个原理图对象模型:

object model

因此,由于实现的接口集,每个对象可能具有许多属性,然后变成相对较重的对象。创建所有可能的 - 当然合理的 - 对象可以是解决这个问题的一种方法(即Pipe_Designed v.s. Pipe_Designed_NeedInspection),但是我现在有大量的接口,这使得它很难。 我想知道是否有办法拥有动态属性,类似于以下对话框,允许最终用户为他/她的新对象选择可用的功能。

dialog

3 个答案:

答案 0 :(得分:2)

你想要的是Properties pattern。查看来自Steve Yegge on this

的冗长乏味但又很聪明的文章

答案 1 :(得分:1)

如果您的意思是公共属性的数量,请使用显式接口实现。

如果您指的是字段(以及稀疏对象的对象空间):您始终可以使用属性包来实现属性。

对于C#示例:

string IDesigned.ApprovedBy {
    get {return GetValue<string>("ApprovedBy");}
    set {SetValue("ApprovedBy", value);}
}

带有值的字典:

readonly Dictionary<string, object> propValues =
    new Dictionary<string, object>();
protected T GetValue<T>(string name)
{
    object val;
    if(!propValues.TryGetValue(name, out val)) return default(T);
    return (T)val;
}
protected void SetValue<T>(string name, T value)
{
    propValues[name] = value;
}

请注意,SetValue也是任何通知的好地方 - 例如,.NET中的INotifyPropertyChanged来实现观察者模式。许多其他架构都有类似的东西。您可以对对象键执行相同的操作(例如EventHandlerList如何工作),但字符串键更易于理解;-p

这只占用了正在使用的属性所需的空间。

最后一个选项是封装各个方面;

class Foo {
    public bool IsDesigned {get {return Design != null;}}
    public IDesigned Design {get;set;}
    // etc
}

此处Foo未实现任何接口,但提供对它们的访问权限。

答案 2 :(得分:1)

我想也许你在“Road”和“Pipe”类中放了太多角色,因为你对动态属性的需求似乎来自你模型中工件的各种状态/阶段。我会考虑使用关联到不同类的显式模型,而不是使用接口将所有内容放在“Road”或“Pipe”类中。