Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Design whether a Class Property has Changed?

I have a class with about 20 properties but I'd simplify it for this question:

public class Product
{
   public int Id { get; set; }
   public string Name { get; set; }
}

I'd like to have a class or property that identifies whether my class is dirty. By this I mean to identify whether any of its values have changed?

There are 3 design approaches I can take:

1) When setting the property inside the class, I check whether the property IsDirty.

public string Name 
{
    get { return this._name; }
    set { if (this._name != value) { this.IsDirty = true; this._name = value; }
}

2) When setting the property from outside the class, I check whether the property IsDirty.

e.g.

if (p.Name != newName)
{
 p.IsDirty = true;
 p.Name = newName; 
}

This approach forces me to add lots of ifs in the client class. Some properties are even collections or even reference objects so the number of lines would be increased even.

3) When the object is ready to be saved, then I check whether any properties IsDirty by getting a cloned object and checking the equality.

This would have a poorer performance as I would have to clone or load again the original object then compare the properties one by one.

Which one is the best design? or is there any other design pattern that can help with this?

like image 801
The Light Avatar asked Jan 20 '14 13:01

The Light


2 Answers

Another option would be to Implement the INotifyPropertyChanged Interface.

Please note that this will help you make thing more tidy and your API clearer, but as far as internal implementation regarding keeping track after changes, It is still up to you to implement. I think this goes along best with your Option #1

like image 195
Avi Turner Avatar answered Oct 16 '22 18:10

Avi Turner


Option 1 is clearly best: it puts the responsibility of tracking dirtiness where it belongs: inside the object. Option 2 is out because as you mentioned, you are forcing this responsibility onto the clients of your classes. And option 3 has the additional problem as you mentioned of performance.

Incidentally, you should look into a proxy implementation using DynamicProxy. This will allow your code to look like this:

public class Product
{
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
}

and with the judicious use of interceptors, you can get the behaviour you want. You can write an interceptor to intercept any "sets" and do some logic inside, such as setting an IsDirty flag.

like image 35
CSJ Avatar answered Oct 16 '22 20:10

CSJ