2010-02-08 11 views
16

Powiedzmy mam klasy takich jak:Czy klasa powinna się sprawdzać samodzielnie, czy utworzyć inną klasę, aby ją zweryfikować?

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

i jeśli chcę utworzyć metody:

const bool validate() const; 

które zasadniczo sprawdza, czy 4 pola zawierają poprawne wartości.

Czy funkcja validate() powinna być częścią klasy NavigationData, czy też powinienem utworzyć coś takiego jak NavigationDataValidator, która zawiera metodę sprawdzania poprawności (const NavigationData &).

Po prostu podam prosty przykład, oczywiście moja prawdziwa klasa jest o wiele bardziej skomplikowana. Szukam dobrych zasad OO.

Mówiąc inaczej: biorąc pod uwagę metodę, skąd wiemy, czy powinna należeć do klasy, czy powinna należeć do oddzielnej klasy?

Odpowiedz

20

Zazwyczaj na klasie spoczywa odpowiedzialność za utrzymanie logicznie spójnego i prawidłowego stanu wewnętrznego. Na przykład, Person może mieć konstruktor, który wymaga zarówno imienia i nazwiska, jeśli operacje na Person są bez znaczenia bez tych danych.

Jednak „logicznie spójny i poprawny” różni się od „ma sens w domenie”, więc czasem jest obowiązkiem klasy zewnętrznej w celu zapewnienia, że ​​zasady domeny są przestrzegane. Na przykład PersonValidator może wymagać, aby numer Person zawierał numer telefonu w USA. Ale Person niekoniecznie musi wiedzieć o tym, czy w USA jest PhoneNumber czy nie.

Dobrą zasadą jest to, że jeśli poza danymi, które już należą do klasy, wymagane są reguły stanu lub domeny zewnętrzne poza klasą, warto rozważyć przeprowadzenie zewnętrznej weryfikacji. Możesz także scentralizować sprawdzanie poprawności w klasie zewnętrznej, jeśli stan instancji klasy może pochodzić z wielu źródeł (np. Bazy danych, formularza internetowego, pliku itp.).

+1

+1 Myślę, że ostatnie punkty prawie zawsze zastępują pierwsze. – blank

1

Powiedziałbym, że to zależy. Jeśli dane klasy można walidować w izolacji, umieściłbym tę metodę w klasie, ale jeśli sprawdzanie poprawności wymaga kontekstu, utworzyłbym klasę weryfikatora opartą na pewnym interfejsie.

1

Zależy ...

Czasami walidacje nie są częścią samej klasy, lecz logiki biznesowej i dodanie go do klasy uniemożliwiłyby powtórnego wykorzystania, a więc korzystanie z klasą Members jest dobra. W przeciwnym razie klasa powinna być w stanie się sprawdzić.

1

Powiedziałbym, że powinien sprawdzać poprawność, o ile prawidłowe wartości nie zależą od tego, jakie inne klasy używają danych nawigacyjnych.

Zasadniczo, tak długo jak szerokość geograficzna i wysokość muszą zawsze wynosić od +/- 90 stopni, a długość i szerokość zawsze muszą wynosić od +/- 180 stopni, należy zachować walidator w klasie.

(Nawiasem mówiąc, co o pozycji?)

+0

hehe, dzięki za wskazanie pozycji na zewnątrz. Po prostu tworzę losowy przykład. ale tak, w mojej prawdziwej klasie nagłówek jest zawarty. =) – sivabudh

2

Twoja klasa powinny być zaprojektowane w taki sposób i zapewnić takie metody sprawdzania poprawności() jest zawsze prawdziwe:

  • po każdej publicznego konstruktora wywoływany
  • przed i po wszelkie metody publicznego jest wywoływana
  • (w C++ - gruntu) przed destruktor jest wywoływany

Metody sprawdzania poprawności() są nazywane niezmiennikami klasy i są ważną częścią Design by Contract.

7

Właściwa odpowiedź to: to zależy od.

Naturalnym miejscem do umieszczenia takiej logiki obiektowej jest sam obiekt. Czasami reguły sprawdzania poprawności mogą być zależne od mechanizmu reguł lub jakiegoś większego "szkieletu", który sprawdza poprawność. Inną sytuacją, w której nie chcesz wykonywać sprawdzania poprawności wewnątrz obiektu, jest sprawdzanie poprawności w innej warstwie lub warstwie lub aplikacji, takiej jak warstwa widoku.

1

To zależy od kontekstu. Czasami twój obiekt jest całkowicie poprawny wewnętrznie, ale w kontekście jego wartości nie są akceptowane.

Jeśli masz prosty obiekt przenoszenia danych, prawdopodobnie nie powinien sam się sprawdzać.

Jeśli posiadasz klasę Modelu Domeny, powinna ona przeprowadzić pewne sprawdzenie.

P.S. tylko moje osobiste preferencje: isValid() zamiast validate(), gdy metoda zwraca wartość boolean.

+0

dziękuję za komentarz isValid(), zgadzam się. – sivabudh

0

Jak już powiedziano, to zależy.

Ale w twoim przypadku, chciałbym przejść do innego rozwiązania, stworzyć nową klasę niezmienna przez współrzędne geograficzne

class GeoCoordinates 
{ 
    double Latitude; 
    double Longitude; 
} 

I niech ta klasa potwierdzić, że szerokość i długość geograficzna są w prawidłowych granicach. Prawdopodobnie będziesz potrzebować również innych miejsc, na przykład.

class Airport 
{ 
    GeoCoordinates Location; 
    ... 
} 
Powiązane problemy