在上一个问题“对象模型设计中有哪些重要规则”之后,现在我想问一下:
有没有办法为类实例提供动态属性?
假设我们有这个原理图对象模型:
因此,由于实现的接口集,每个对象可能具有许多属性,然后变成相对较重的对象。创建所有可能的 - 当然合理的 - 对象可以是解决这个问题的一种方法(即Pipe_Designed v.s. Pipe_Designed_NeedInspection),但是我现在有大量的接口,这使得它很难。 我想知道是否有办法拥有动态属性,类似于以下对话框,允许最终用户为他/她的新对象选择可用的功能。
答案 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”类中。