Jestem całkiem nowy w zasadach projektowania SOLID . Rozumiem ich przyczynę i korzyści, ale jednak nie stosuję ich do mniejszego projektu, który chciałbym zreformować jako praktyczne ćwiczenie z wykorzystaniem zasad SOLID. Wiem, że nie ma potrzeby zmiany aplikacji, która działa idealnie, ale i tak chcę ją zrefaktoryzować, aby zyskać doświadczenie projektowe dla przyszłych projektów.
Aplikacja ma następujące zadanie (właściwie o wiele więcej, ale bądźmy prostsze): musi odczytać plik XML zawierający definicje tabeli bazy danych / kolumny / widoku itp. I utworzyć plik SQL, którego można użyć do utworzenia schemat bazy danych ORACLE.
(Uwaga: powstrzymaj się od dyskusji, dlaczego go potrzebuję lub dlaczego nie używam XSLT i tak dalej, istnieją powody, ale są one nie na temat).
Na początek postanowiłem spojrzeć tylko na tabele i ograniczenia. Jeśli zignorujesz kolumny, możesz podać je w następujący sposób:
Ograniczenie jest częścią tabeli (a ściślej częścią instrukcji CREATE TABLE), a ograniczenie może również odnosić się do innej tabeli.
Najpierw wyjaśnię, jak teraz wygląda aplikacja (nie stosując SOLID):
W tej chwili aplikacja ma klasę „Tabela”, która zawiera listę wskaźników do ograniczeń należących do tabeli oraz listę wskaźników do ograniczeń odnoszących się do tej tabeli. Za każdym razem, gdy zostanie ustanowione połączenie, zostanie również ustanowione połączenie wsteczne. Tabela ma metodę createStatement (), która z kolei wywołuje funkcję createStatement () każdego ograniczenia. Wspomniana metoda sama użyje połączeń z tabelą właściciela i tabelą odniesienia, aby pobrać ich nazwy.
Oczywiście nie dotyczy to w ogóle SOLID. Na przykład istnieją zależności cykliczne, które rozprężają kod pod względem wymaganych metod „dodawania” / „usuwania” i niektórych destrukterów dużych obiektów.
Jest więc kilka pytań:
- Czy powinienem rozwiązać zależności cykliczne za pomocą wstrzykiwania zależności? Jeśli tak, to przypuszczam, że Ograniczenie powinno otrzymać tabelę właściciela (i opcjonalnie odnośnik) w swoim konstruktorze. Ale jak w takim razie mógłbym przeglądać listę ograniczeń dla pojedynczej tabeli?
- Jeśli zarówno klasa Table przechowuje stan samego siebie (np. Nazwę tabeli, komentarz do tabeli itp.), Jak i linki do Ograniczeń, to czy te jedno lub dwa „obowiązki” mają na myśli zasadę pojedynczej odpowiedzialności?
- W przypadku, gdy 2. ma rację, czy powinienem po prostu utworzyć nową klasę w logicznej warstwie biznesowej, która zarządza łączami? Jeśli tak, 1. oczywiście nie byłoby już istotne.
- Czy metody „createStatement” powinny być częścią klas Table / Constraint, czy też mam je przenieść? Jeśli tak to gdzie? Jedna klasa menedżera na każdą klasę przechowywania danych (tj. Tabela, ograniczenie, ...)? Czy raczej utworzyć klasę menedżera dla linku (podobną do 3.)?
Ilekroć próbuję odpowiedzieć na jedno z tych pytań, znajduję się gdzieś w kółko.
Problem oczywiście staje się o wiele bardziej złożony, jeśli uwzględnisz kolumny, indeksy i tak dalej, ale jeśli pomożecie mi z prostą kwestią związaną z tabelą / ograniczeniami, może resztę samodzielnie opracuję.