Załóżmy na przykład, że masz aplikację o powszechnie udostępnianej klasie o nazwie User
. Ta klasa ujawnia wszystkie informacje o użytkowniku, jego identyfikatorze, nazwie, poziomach dostępu do każdego modułu, strefie czasowej itp.
Dane użytkownika są oczywiście szeroko przywoływane w całym systemie, ale z jakiegokolwiek powodu system jest skonfigurowany tak, aby zamiast przekazywać ten obiekt użytkownika do zależnych od niego klas, po prostu przekazujemy z niego poszczególne właściwości.
Klasa, która wymaga identyfikatora użytkownika, po prostu będzie wymagała GUID userId
jako parametru, czasami możemy również potrzebować nazwy użytkownika, aby była przekazywana jako osobny parametr. W niektórych przypadkach jest to przekazywane do poszczególnych metod, więc wartości nie są w ogóle utrzymywane na poziomie klasy.
Za każdym razem, gdy potrzebuję dostępu do innej informacji z klasy User, muszę wprowadzić zmiany, dodając parametry, a gdy dodanie nowego przeciążenia nie jest właściwe, muszę zmienić każde odwołanie do metody lub konstruktora klasy.
Użytkownik jest tylko jednym przykładem. Jest to powszechnie praktykowane w naszym kodzie.
Czy mam rację, sądząc, że jest to naruszenie zasady otwartej / zamkniętej? Nie chodzi tylko o zmianę istniejących klas, ale przede wszystkim o ich utworzenie, aby w przyszłości najprawdopodobniej konieczne będą szeroko zakrojone zmiany?
Gdybyśmy tylko przeszli przez User
obiekt, mógłbym dokonać niewielkiej zmiany w klasie, z którą pracuję. Jeśli muszę dodać parametr, być może będę musiał wprowadzić dziesiątki zmian w odniesieniach do klasy.
Czy ta praktyka narusza jakieś inne zasady? Może inwersja zależności? Chociaż nie odwołujemy się do abstrakcji, istnieje tylko jeden rodzaj użytkownika, więc nie ma potrzeby posiadania interfejsu użytkownika.
Czy naruszane są inne zasady inne niż SOLID, takie jak podstawowe zasady programowania obronnego?
Czy mój konstruktor powinien wyglądać tak:
MyConstructor(GUID userid, String username)
Albo to:
MyConstructor(User theUser)
Opublikował:
Sugerowano, że odpowiedź na pytanie znajduje się w „Pass ID czy Object?”. To nie odpowiada na pytanie, w jaki sposób decyzja o przejściu w którąkolwiek stronę wpływa na próbę przestrzegania zasad SOLID, która stanowi sedno tego pytania.
I
in SOLID
? MyConstructor
w zasadzie mówi teraz: „Potrzebuję Guid
a string
”. Dlaczego więc nie mieć interfejsu zapewniającego Guid
ai a string
, niech User
implementuje ten interfejs i pozwala MyConstructor
zależeć od instancji implementującej ten interfejs? A jeśli potrzeba MyConstructor
zmiany, zmień interfejs. - Pomogło mi bardzo pomyśleć o interfejsach, które „należałyby” do konsumenta, a nie do dostawcy . Pomyśl więc „jako konsument potrzebuję czegoś, co robi to i to” zamiast „jako dostawca mogę to zrobić i tamto”.