1

在上一个问题“对象模型设计中的重要规则是什么”之后,现在我想问这个:

有没有办法让类实例具有动态属性?

假设我们有这个示意图对象模型:

对象模型

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

对话

4

3 回答 3

2

你想要的是Properties pattern. 查看Steve Yegge 的冗长而无聊但聪明的文章

于 2009-02-01T10:18:13.407 回答
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这也是任何通知的好地方——例如,INotifyPropertyChanged在 .NET 中实现观察者模式。许多其他架构也有类似的东西。您可以对对象键执行相同的操作(例如如何EventHandlerList工作),但字符串键更易于理解;-p

这只会占用与正在使用的属性一样多的空间。

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

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

这里Foo没有实现任何接口,但提供了对它们作为属性的访问。

于 2009-02-01T10:19:18.520 回答
1

我认为您可能在“Road”和“Pipe”类中添加了太多角色,因为您对动态属性的需求似乎源自模型中工件的各种状态/阶段。我会考虑使用与不同类的关联来创建一个显式模型,而不是使用接口将所有内容放在“Road”或“Pipe”类中。

于 2009-02-01T10:21:05.257 回答