2010-02-08 15 views
16

Sagen wir, ich habe eine Klasse wie:Sollte sich eine Klasse selbst validieren oder eine andere Klasse erstellen, um sie zu validieren?

class NavigationData 
{ 
    float roll; 
    float pitch; 
    double latitude; 
    double longitude; 
} 

und wenn ich will, ein Verfahren schaffen:

const bool validate() const; 

das anzeigt, ob bestätigt im Wesentlichen die vier Felder gültige Werte enthalten.

Sollte validate() Teil der NavigationData-Klasse sein, oder sollte ich etwas wie eine NavigationDataValidator erstellen, die eine validate (const NavigationData &) -Methode enthält.

Ich gebe nur ein einfaches Beispiel, offensichtlich ist meine echte Klasse viel komplizierter als das. Ich suche nach guten OO-Prinzipien.

Oder anders ausgedrückt: Wie können wir wissen, ob es zu einer Klasse gehört oder zu einer eigenen Klasse gehört?

Antwort

20

In der Regel liegt es in der Verantwortung einer Klasse, sicherzustellen, dass sie einen logisch konsistenten und gültigen internen Zustand beibehält. Zum Beispiel kann Person einen Konstruktor haben, der sowohl einen Vor- als auch einen Nachnamen benötigt, wenn die Operationen Person ohne diese Daten bedeutungslos sind.

jedoch „logisch konsistent und gültig“ von anders „macht Sinn in der Domäne“, so ist es manchmal in der Verantwortung einer externen Klasse, dass Domain-Regeln, um sicherzustellen, befolgt werden. Zum Beispiel kann PersonValidator erfordern, dass Person eine Telefonnummer hat, die in den USA ist. Aber Person sollte nicht unbedingt etwas darüber wissen, ob ein PhoneNumber in den USA ist oder nicht.

Eine gute Faustregel besagt, dass wenn außerhalb der Klasse externe Status- oder Domänenregeln zusätzlich zu den Daten benötigt werden, die bereits zur Klasse gehören, Sie eine externe Validierung in Betracht ziehen sollten. Möglicherweise möchten Sie auch die Validierung in einer externen Klasse zentralisieren, wenn der Status der Instanzen der Klasse aus mehreren Quellen stammen kann (z. B. Datenbank, Webformular, Datei usw.).

+1

+1 Ich denke die letzten Punkte überschreiben fast immer die erste. – blank

1

Ich würde sagen, es kommt darauf an. Wenn die Daten der Klasse isoliert validierbar sind, würde ich die Methode in die Klasse einfügen, aber wenn die Validierung einen Kontext erfordert, würde ich eine Validator-Klasse basierend auf einer Schnittstelle erstellen.

1

Hängt ...

Manchmal sind die Validierungen nicht Teil der Klasse selbst, sondern Business-Logik, und es in die Klasse würde das Hinzufügen Wiederverwendung verhindern, und daher ist die Verwendung eines Validieren Klasse ist gut. Andernfalls sollte die Klasse in der Lage sein, sich selbst zu validieren.

1

Ich würde sagen, es validiert sich selbst, solange die gültigen Werte nicht davon abhängen, welche anderen Klassen NavigationData verwenden.

Solange der Breitengrad und die Tonhöhe immer zwischen +/- 90 Grad liegen müssen und der Längen- und Breitengrad immer zwischen +/- 180 Grad liegt, halten Sie den Validator in der Klasse.

(By the way, was Überschrift?)

+0

hehe, danke für das Ausrichten. Ich erstelle nur ein zufälliges Beispiel. aber ja, in meiner echten Klasse ist Überschrift enthalten. =) – sivabudh

2

Ihre Klasse sollte eine solche Art und Weise gestaltet werden, und solche Verfahren bereitzustellen, die Validierung() ist immer wahr:

  • nach einem öffentlichen Konstruktor
  • aufgerufen
  • vor und nach jeder öffentlichen Methode aufgerufen
  • (in C++ - Land) vor destructor aufgerufen wird

Solche validate() Methoden heißen Klassen Invarianten und sind ein wichtiger Teil von Design by Contract.

7

Die richtige Antwort lautet: es kommt darauf an.

Der natürliche Ort, um eine solche Objektlogik zu platzieren, liegt im Objekt selbst. Manchmal können die Validierungsregeln jedoch von einer Rules-Engine oder einer Art von größerem "Framework" abhängig sein, das Dinge validiert. Eine andere Situation, in der Sie keine Validierung innerhalb des Objekts durchführen möchten, ist, wenn die Validierung in einer anderen Schicht oder Schicht oder in der Anwendung, z. B. der Ansichtsebene, enthalten ist.

1

Es hängt vom Kontext ab. Manchmal ist Ihr Objekt absolut gültig, aber im Kontext sind seine Werte nicht akzeptabel.

Wenn Sie ein einfaches Datenübertragungsobjekt haben, sollte es sich wahrscheinlich nicht selbst validieren.

Wenn Sie eine Klasse von Domain Model haben, sollte es eine Validierung durchführen.

P.S. nur meine persönliche Vorliebe: isValid() statt validate(), wenn die Methode einen booleschen Wert zurückgibt.

+0

danke für den isValid() Kommentar, stimme ich zu. – sivabudh

0

Wie es schon gesagt wurde, kommt es darauf an.

Aber in Ihrem Fall würde ich für eine andere Lösung gehen, neue unveränderliche Klasse schaffen für geo

class GeoCoordinates 
{ 
    double Latitude; 
    double Longitude; 
} 

koordiniert und diese Klasse, die geografische Breite und Länge sind im Rahmen der gültigen Grenzen validieren lassen. Sie werden wahrscheinlich auch diese anderen Orte benötigen, zum Beispiel.

class Airport 
{ 
    GeoCoordinates Location; 
    ... 
} 
Verwandte Themen