Cześć.
Załóżmy, że mamy sobie legacy kod i uber encje User
:
class User {
private long id;
private String firstName;
private String lastName;
private boolean confirmed;
private String phoneNumber;
private String pinToConfirmPhone;
private boolean phoneConfirmed;
// business methods
}
która stoi na jednej tabelce SQLowej USER
z odpowiadającymi 1 do 1 polami.
Teraz chcemy sobie zrobić refactor i widzimy, że mamy tutaj część pól odpowiadającym rejestracji/potwierdzaniu użytkownika oraz część związana z kontaktem z nim za pomocą nr tel. Robimy sobie zatem osobne klasy:
class Registration {
private long id;
private String firstName;
private String lastName;
private boolean confirmed;
// business methods
}
class PhoneContact {
private long id;
private String phoneNumber;
private String pinToConfirmPhone;
private boolean phoneConfirmed;
// business methods
}
Mamy sobie teraz jakieś dwa osobne agregaty i rozbijamy je do osobnych modułów, a w przyszłości może nawet do osobnych mikroserwisów. W celu uproszczenia nie wspominam o tym, że przy refaktorze robię value objecty zamiast prymitywów.
Moje pytania i wątpliwości:
- Czy te dwa agregaty mogą sobie nadal leżeć na tej samej jednej tabeli
USER
czy też warto ją znormalizować i wydzielić tabelęPHONE_CONTACT
? - Tabele
USER
iPHONE_CONTACT
były by tak naprawdę w relacji 1 do 1. Czy tabelaPHONE_CONTACT
powinna mieć swoje ID to samo co ID usera, czy powinna mieć raczej swój unikalny id i klucz obcy doUSER
w jakiejś kolumnieUSER_ID
? To wydaje mi się trochę sztuczne, bo i tak jest relacja 1 do 1. Mogę też nałożyć klucz obcy na kolumnęID
w tabeliPHONE_CONTACT
i idkiUSER
iPHONE_CONTACT
będą takie same. - Nie bardzo wiem, w którąś iść stronę jeśli chodzi o poprzednie 2 punkty i to też prowadzi do pewnych rozróżnień w domenie, a mówi się, że infra nie powinna wpływać na domenę. Dzieje się tak dlatego, że jeśli będą te 2 agregaty na jednej tabeli to przy wyciąganiu po id z repo
PhoneContact
dostanę ten obiekt z nullami w środku jeśli nikt z nim wcześniej nic nie robił. Id będę znał, bo w systemie najpierw następuje rejestracja a dopiero potem można updatować sobie nr. Jeśli natomiast będzie to osobna tabela to wyciągając po id pierwszy raz dostanę pustego Optionala. To wpływa na zmiany domenie ponieważ w zależności od rozwiązania w tabelkach w DB wystarczy mi albo samofindById
poPhoneContact
w przypadku jednej tabeli albo muszę zrobićfindById
+orElse(createNewPhone())
w przypadku dwóch rozdzielonych tabel. W którą stronę iść? Czy gdzieś źle kombinuję?
Pozdr.