Tło:
Projektuję aplikację serwera i tworzę osobne biblioteki DLL dla różnych podsystemów. Dla uproszczenia załóżmy, że mam dwa podsystemy: 1) Users
2)Projects
Publiczny interfejs użytkownika ma metodę taką jak:
IEnumerable<User> GetUser(int id);
A publiczny interfejs projektów ma metodę taką jak:
IEnumerable<User> GetProjectUsers(int projectId);
Na przykład, kiedy musimy wyświetlić użytkowników dla określonego projektu, możemy zadzwonić GetProjectUsers
, co da obiekty z wystarczającą ilością informacji do wyświetlenia w siatce danych lub podobnej.
Problem:
Idealnie, Projects
podsystem nie powinien również przechowywać informacji o użytkownikach i powinien po prostu przechowywać identyfikatory użytkowników uczestniczących w projekcie. Aby służyć GetProjectUsers
, musi wywołać GetUser
w Users
systemie dla każdego identyfikatora użytkownika przechowywane we własnej bazie danych. Wymaga to jednak wielu osobnych GetUser
wywołań, powodując wiele osobnych zapytań SQL w User
podsystemie. Tak naprawdę nie testowałem tego, ale ten gadatliwy projekt wpłynie na skalowalność systemu.
Jeśli odłożyłbym na bok separację podsystemów, mógłbym przechowywać wszystkie informacje w jednym schemacie dostępnym dla obu systemów i Projects
po prostu zrobić, JOIN
aby uzyskać wszystkich użytkowników projektu w jednym zapytaniu. Projects
musiałby także wiedzieć, jak generować User
obiekty z wyników zapytania. Ale to łamie separację, która ma wiele zalet.
Pytanie:
Czy ktoś może zasugerować sposób na zachowanie separacji przy jednoczesnym unikaniu wszystkich tych indywidualnych GetUser
połączeń podczas GetProjectUsers
?
Na przykład, pomyślałem, że miałem dla użytkowników, aby dać systemom zewnętrznym możliwość „otagowania” użytkowników parą wartość-etykieta oraz żądania użytkowników o określonej wartości, np .:
void AddUserTag(int userId, string tag, string value);
IEnumerable<User> GetUsersByTag(string tag, string value);
Następnie system Projekty mógłby oznaczyć każdego użytkownika dodawanym do projektu:
AddUserTag(userId,"project id", myProjectId.ToString());
a podczas GetProjectUsers może poprosić wszystkich użytkowników projektu w jednym wywołaniu:
var projectUsers = usersService.GetUsersByTag("project id", myProjectId.ToString());
część, której nie jestem pewien, to: tak, użytkownicy są agnostycy projektów, ale tak naprawdę informacje o członkostwie projektu są przechowywane w systemie użytkowników, a nie projektów. Po prostu nie czuję się naturalnie, więc próbuję ustalić, czy brakuje mi tutaj dużej wady.