5 Stimmen

Wie man überwacht, ob sich ein Klassenattribut geändert hat?

Ich habe eine Klasse mit etwa 20 Eigenschaften, aber ich würde sie für diese Frage vereinfachen:

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

Ich möchte eine Klasse oder Eigenschaft haben, die identifiziert, ob meine Klasse "dirty" ist. Damit meine ich, ob sich eines ihrer Werte geändert hat?

Es gibt 3 Designansätze, die ich verfolgen kann:

1) Beim Setzen der Eigenschaft innerhalb der Klasse überprüfe ich, ob die Eigenschaft IsDirty ist.

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

2) Beim Setzen der Eigenschaft von außerhalb der Klasse überprüfe ich, ob die Eigenschaft IsDirty ist.

z.B.

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

Dieser Ansatz zwingt mich, viele if-Abfragen in der Client-Klasse hinzuzufügen. Einige Eigenschaften sind sogar Sammlungen oder Referenzobjekte, so dass die Anzahl der Zeilen sogar erhöht werden würde.

3) Wenn das Objekt bereit ist, gespeichert zu werden, überprüfe ich, ob irgendwelche Eigenschaften IsDirty sind, indem ich ein geklontes Objekt hole und die Gleichheit überprüfe.

Dies hätte eine schlechtere Leistung, da ich das Originalobjekt klonen oder erneut laden müsste und dann die Eigenschaften nacheinander vergleichen müsste.

Welches ist das beste Design? Oder gibt es ein anderes Designmuster, das dabei helfen kann?

5voto

Avi Turner Punkte 9662

Eine andere Option wäre die Implementierung des INotifyPropertyChanged Interfaces.

Bitte beachten Sie, dass Ihnen dies helfen wird, die Dinge aufgeräumter und Ihre API klarer zu gestalten, aber bezüglich der internen Implementierung zur Verfolgung von Änderungen liegt es weiterhin an Ihnen, dies umzusetzen. Ich denke, dass dies am besten zu Ihrer Option #1 passt.

1voto

CSJ Punkte 3391

Option 1 ist eindeutig am besten: Es legt die Verantwortung für das Tracking von Verschmutzungen dort, wo sie hingehört: innerhalb des Objekts. Option 2 fällt weg, da du, wie du erwähnt hast, diese Verantwortung den Clients deiner Klassen aufdrängst. Und Option 3 hat das zusätzliche Problem, wie du erwähnt hast, der Leistung.

Übrigens solltest du eine Proxy-Implementierung mit DynamicProxy in Betracht ziehen. Dies ermöglicht es Ihrem Code, wie folgt auszusehen:

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

und mit dem klugen Einsatz von Interceptrs können Sie das gewünschte Verhalten erhalten. Sie können einen Interceptor schreiben, um alle "sets" abzufangen und etwas Logik innerhalb durchzuführen, wie z.B. das Setzen eines IsDirty-Flags.

0voto

duffymo Punkte 298898

Eine weitere Idee wäre, dies zu einem [GoF](http://de.wikipedia.org/wiki/Entwurfsmuster_(Vorlage:IPA) rel=) Observable zu machen und interessierte Observer Parteien ihre Interesse an Änderungen registrieren zu lassen. Es handelt sich dabei um einen ereignisbasierten Ansatz.

0voto

The Light Punkte 25263

Dies ist die beste Lösung und entspricht dem SRP-Prinzip sehr gut. Ich habe die folgenden Klassen erstellt:

  • ProductWithChangeDetection; verwendet das Decorator-Muster, um dieses neue Feature einem vorhandenen Produktobjekt hinzuzufügen

  • ProductChangeDetector; enthält Logik für die Überprüfung und Benachrichtigung. Derzeit wird nur die ChangeDetected-Eigenschaft freigegeben, aber wenn mehr Komplexität erforderlich ist, sollte man das INotifyPropertyChange-Interface implementieren.

  • ProductEquitable; implementiert IEquitable und hat einige Überladungen zur Überprüfung, ob zwei Objekte/ Eigenschaften gleich sind

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X