问题
After the previous question "What are the important rules in Object Model Design", now I want to ask this:
Is there any way to have dynamic properties for class instances?
Suppose that we have this schematic object model:
So, each object could have lots of properties due to the set of implemented Interfaces, and then become relatively heavy object. Creating all the possible -and of course reasonable- object can be a way for solving this problem (i.e. Pipe_Designed v.s. Pipe_Designed_NeedInspection), but I have a large number of interfaces by now, that make it difficult. I wonder if there is a way to have dynamic properties, something like the following dialog to allow the end user to select available functionalities for his/hers new object.
回答1:
What you want is Properties pattern. Check out long and boring but clever article from Steve Yegge on this
回答2:
I think maybe you're putting too many roles into the "Road" and "Pipe" classes, because your need for dynamic properties seems to derive from various states/phases of the artifacts in your model. I would consider making an explicit model using associations to different classes instead of putting everything in the "Road" or "Pipe" class using interfaces.
回答3:
If you mean the number of public properties, use explicit interface implementation.
If you mean fields (and object space for sparse objects): you can always use a property bag for the property implementation.
For a C# example:
string IDesigned.ApprovedBy {
get {return GetValue<string>("ApprovedBy");}
set {SetValue("ApprovedBy", value);}
}
with a dictionary for the values:
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;
}
Note that SetValue would also be a good place for any notifications - for example, INotifyPropertyChanged in .NET to implement the observer pattern. Many other architectures have something similar. You can do the same with object keys (like how EventHandlerList works), but string keys are simpler to understand ;-p
This only then takes as much space as the properties that are actively being used.
A final option is to encapsulate the various facets;
class Foo {
public bool IsDesigned {get {return Design != null;}}
public IDesigned Design {get;set;}
// etc
}
Here Foo doesn't implement any of the interfaces, but provides access to them as properties.
来源:https://stackoverflow.com/questions/500540/dynamic-properties-for-object-instances