Pisanie rzeczowników, czasowników, przymiotników to świetne podejście, ale wolę myśleć o projektowaniu klas jako o zadawaniu pytania, jakie dane powinny być ukryte ?
Wyobraź sobie, że masz Query
przedmiot i Database
przedmiot:
Query
Obiekt pomoże Ci tworzyć i przechowywać zapytania - sklep, jest kluczem tutaj, jako funkcja może pomóc utworzyć tak łatwo. Może uda się zatrzymać: Query().select('Country').from_table('User').where('Country == "Brazil"')
. Nie ma znaczenia dokładnie składnia - to twoja praca! - kluczem jest obiekt, który pomaga ci coś ukryć , w tym przypadku dane niezbędne do przechowywania i wysyłania zapytania. Siła obiektu pochodzi ze składni używania go (w tym przypadku sprytnego tworzenia łańcucha) i nie musi wiedzieć, co przechowuje, aby działał. Jeśli zostanie to zrobione poprawnie, Query
obiekt może wysyłać zapytania do więcej niż jednej bazy danych. Wewnętrznie przechowuje określony format, ale można go łatwo konwertować na inne formaty podczas drukowania (Postgres, MySQL, MongoDB).
Zastanówmy się teraz nad Database
obiektem. Co to ukrywa i przechowuje? Oczywiście nie może przechowywać pełnej zawartości bazy danych, ponieważ właśnie dlatego mamy bazę danych! Więc o co chodzi? Celem jest ukrycie sposobu działania bazy danych przed osobami korzystającymi z Database
obiektu. Dobre klasy upraszczają rozumowanie podczas manipulowania stanem wewnętrznym. W przypadku tego Database
obiektu można ukryć sposób działania wywołań sieciowych lub wsadowych zapytań lub aktualizacji albo zapewnić warstwę buforowania.
Problem w tym, że ten Database
obiekt jest OGROMNY. Pokazuje, jak uzyskać dostęp do bazy danych, więc pod osłonami może zrobić wszystko i wszystko. Oczywiście praca w sieci, buforowanie i przetwarzanie wsadowe są dość trudne w zależności od systemu, więc ukrycie ich byłoby bardzo pomocne. Ale, jak zauważy wiele osób, baza danych jest niesamowicie złożona, a im dalej od surowych wywołań bazy danych otrzymujesz, tym trudniej jest dostroić się do wydajności i zrozumieć, jak to działa.
To jest podstawowy kompromis z OOP. Jeśli wybierzesz odpowiednią abstrakcję, ułatwi to kodowanie (ciąg znaków, tablica, słownik), jeśli wybierzesz abstrakcję, która jest zbyt duża (baza danych, EmailManager, NetworkingManager), może to stać się zbyt skomplikowane, aby naprawdę zrozumieć, jak to działa lub co robić oczekiwać. Celem jest ukrycie złożoności , ale pewna złożoność jest konieczna. Dobrą praktyczną zasadą jest unikanie Manager
obiektów, a zamiast tego tworzenie klas, które są podobne structs
- wszystko, co robią, to przechowywanie danych, z pewnymi pomocniczymi metodami tworzenia / manipulowania danymi, aby ułatwić Ci życie. Na przykład w przypadku EmailManager
uruchomienia funkcji wywoływanej, sendEmail
która przyjmuje Email
obiekt. To jest prosty punkt wyjścia, a kod jest bardzo łatwy do zrozumienia.
Na przykład zastanów się, jakie dane muszą być razem, aby obliczyć to, czego szukasz. Jeśli chcesz na przykład wiedzieć, jak daleko chodzi zwierzę, możesz mieć zajęcia AnimalStep
i AnimalTrip
(zbiór AnimalSteps). Teraz, gdy każda podróż ma wszystkie dane dotyczące kroków, powinna być w stanie dowiedzieć się o tym, być może AnimalTrip.calculateDistance()
ma sens.