Wie kann ich eine Objektinitialisierung abbrechen?

7

Ich schreibe ein Objekt, das immer bestimmte Werte haben muss. Vor allem muss es immer einen Wert für Name -Eigenschaft haben.

%Vor%

Jetzt gibt es einige Geschäftsregeln, die ich in dieser Klasse implementieren muss. Eine davon ist, dass die Eigenschaft Name ein eindeutiger Name sein muss. Also, ich würde denken, dass der Initialisierer für dieses Objekt etwas davon aussehen würde:

%Vor%

Aber ich bin mir nicht sicher, wie ich die Objektinitialisierung abbrechen würde. Ist das überhaupt möglich?

Gibt es eine Möglichkeit, eine Objektinitialisierung abzubrechen (zB: setze Objekt auf null) oder gibt es eine bessere Möglichkeit, dies zu erreichen?

    
quakkels 08.05.2012, 14:55
quelle

9 Antworten

3

Die Initialisierung eines Objekts wird abgebrochen, indem im Konstruktor eine Ausnahme ausgelöst wird, und es wird empfohlen, ungültige Eingaben abzulehnen.

%Vor%

Die Geschäftslogik, die Sie im Konstruktor definieren möchten, passt dort nicht. Konstruktoren sollten leicht und nur Instanziierung sein. Das Abfragen einiger Datenquellen ist für einen Konstruktor zu teuer. Aus diesem Grund sollten Sie stattdessen das Factory-Muster verwenden. Mit dem Factory-Muster könnte ein Aufrufer erwarten, dass bei der Objekterstellung etwas Schweres beteiligt ist.

%Vor%

Sie können sehen, dass das Fabrikmuster besser passt, und weil es eine Methode ist, von der ein Anrufer erwartet, dass dort etwas Arbeit stattfindet, indem er es aufruft. Während man bei einem Konstruktor erwarten würde, dass es leicht ist.

Wenn Sie die Konstruktorroute verwenden möchten, sollten Sie eine andere Methode zum Erzwingen Ihrer Geschäftsregeln ausprobieren, z. B. wenn die tatsächliche Einfügung in die Datenquelle versucht wird.

%Vor%     
David Anderson - DCOM 08.05.2012, 15:11
quelle
6

Nun, Sie würden nur eine Ausnahme werfen. Aber ich mag diese Art des Umgangs mit diesem Problem überhaupt nicht. Stattdessen sollten Sie den Benutzer über den Dienst erstellen und den Dienst überprüfen lassen, ob der Name gültig ist oder nicht.

    
jason 08.05.2012 14:57
quelle
4

Ich nehme an, dass Sie eine Exception im Konstruktor des Objekts oder in der Namesetter-Klasse überprüfen und ausgeben können, aber eeeeahhhh, die mit einer Menge von Problemen und gemischten Problemen einhergehen kann. Ich sage, erstellen Sie das Objekt durch eine Fabrik, die diese Überprüfung durchführt und null zurückgibt (oder eine ordnungsgemäß benannte Ausnahme). Oder erstellen Sie das POCO-Objekt und führen Sie die Validierung über eine separate Klasse / Methode durch.

    
Chris Sinclair 08.05.2012 14:57
quelle
3

Anstelle eines öffentlichen Konstruktors sollten Sie eine Methode wie diese und einen privaten Konstruktor verwenden:

%Vor%

Dann könnte Ihr aufrufender Code User myUser = User.CreateUser("Steve"); verwenden und dementsprechend die Rückgabe / Ausnahme von null behandeln.

Es sollte hinzugefügt werden, dass die von Ihnen verwendete Methode, die speichert, welche Benutzernamen verwendet werden, aktualisiert werden sollte, um zu sagen, dass dieser Name in der CreateUser-Methode verwendet wird. Andernfalls, wenn Sie eine Weile warten, bevor Sie dieses Objekt in einer Datenbank oder etwas speichern, werden Sie immer noch Probleme haben. Ich habe den obigen Code aktualisiert, um dies klarer zu machen.

    
quelle
2

Sie sollten wahrscheinlich nach dem doppelten Namen suchen, bevor Sie den Benutzer erstellen.

    
ltiong_sh 08.05.2012 14:57
quelle
2

Persönlich führe ich logische Prüfungen durch, bevor ich instanziiere. Zum Beispiel:

%Vor%

Die PreInsertValidation würde basierend auf Ihren Anforderungen alle Geschäftslogik-Prüfungen durchführen.

    
skaz 08.05.2012 15:01
quelle
0

Was Sie suchen, ist das Muster Identity Map oder eine Art davon. Es ist wahrscheinlich falsch, diese Verantwortung im Objekt selbst zu belassen, es sollte in der Komponente geschehen, die die Entitäten erzeugt. Natürlich sollte die Karte bei Bedarf threadsicher sein, um Rennbedingungen zu vermeiden.

    
Felice Pollano 08.05.2012 15:02
quelle
0

Ich würde damit umgehen, dass ich den Benutzer in der Sammlung habe. Wenn Sie beispielsweise eine Sammlung von Benutzern bearbeiten und diese dann in der Datenbank persistent machen, ist die Persistenzebene für die Überprüfung zuständig. Ich habe es immer für eine schlechte Praxis gehalten, ein Objekt für die Pflege aller anderen Objekte verantwortlich zu machen. Es führt eine Eltern-Kind-Beziehung mit dem Objekt selbst ein, wenn keine vorhanden ist. Ich schlage vor, eine Art von Validierungs-Engine zu implementieren.

    
Mike Calvert 08.05.2012 15:02
quelle
0

Anstatt diese Validierung innerhalb des Objekts selbst vorzunehmen, legen Sie die Erstellung, Validierung und Speicherung dieser Entität in einem Service ab. Dieser Dienst kann ValidationException auslösen, wenn der Benutzername nicht eindeutig ist, und könnte sogar eine Transaktion starten, um sicherzustellen, dass keine Race-Bedingung auftreten kann. Ein gutes Modell, das ich verwende, ist das Befehl / Handler -Muster. Hier ist ein Beispiel:

%Vor%

Sie könnten sogar die Validierung in eine eigene Klasse einfügen.

    
Steven 08.05.2012 15:08
quelle

Tags und Links