Tło:
Projektuję aplikację serwera i tworzę osobne biblioteki DLL dla różnych podsystemów. Dla uproszczenia załóżmy, że mam dwa podsystemy: 1) Users2)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, Projectspodsystem 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ć GetUserw Userssystemie dla każdego identyfikatora użytkownika przechowywane we własnej bazie danych. Wymaga to jednak wielu osobnych GetUserwywołań, powodując wiele osobnych zapytań SQL w Userpodsystemie. 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 Projectspo prostu zrobić, JOINaby uzyskać wszystkich użytkowników projektu w jednym zapytaniu. Projectsmusiałby także wiedzieć, jak generować Userobiekty 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 GetUserpołą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.