#design-patterns #architecture #decoupling
#шаблоны проектирования #архитектура #развязка
Вопрос:
Итак, я пытаюсь выяснить, как (или если это вообще возможно) собрать конкретную программную архитектуру с некоторыми нетрадиционными требованиями. Архитектура имеет уровень обслуживания и, возможно, несколько клиентских уровней, которые используют уровень обслуживания.
Я бы хотел, чтобы уровень обслуживания принимал абстракцию и возвращал абстракцию с конкретными реализациями, определенными клиентскими уровнями, таким образом, чтобы клиенты могли получить любой конкретный результат, который им нужен, без того, чтобы уровень обслуживания знал о типе необходимого вывода.
Я могу решить эту проблему, используя общие или маркерные интерфейсы и результаты прямого литья, но оба они неоптимальны для моих целей, и я надеялся, что у кого-нибудь здесь будет вдохновение, которого мне не хватает.
Это грубый пример общей структуры используемых абстракций, но все они открыты для пересмотра, если этого требует подходящее решение:
interface IServiceResult {
// No idea what methods this should have yet
}
interface IServiceHandler {
IServiceResult CouldNotFindFile();
IServiceResult CouldNotReadFile();
IServiceResult ServiceSuccessful();
}
interface IService {
IServiceResult PerformService(IServiceHandler outcomes);
}
// Console Client Code:
IService service = new Service();
IServiceHandler handler = new ConsoleServiceHandler();
IServiceResult result = service.PerformService(handler);
/* Some process to convert IServiceResult to text to display in the console */
// API Endpoint Client Code:
IService service = new Service();
IServiceHandler handler = new ApiServiceHandler();
IServiceResult result = service.PerformService(handler);
/* Some process to convert IServiceResult to Http Status Code to return to client */
Моя интуиция заключается в том, чтобы иметь какую-то двойную отправку с IServiceResult
помощью, но я не могу разобраться / как получить желаемый результат с этого момента. Любая информация была бы очень признательна.
Ответ №1:
Проблема с тем, что вы пытаетесь сделать, заключается в том, что конкретные типы result
и handler
должны соответствовать, и в системе типов языка нет способа выразить это ограничение. Если вы попытаетесь использовать двойную отправку, вы получите интерфейс, в котором есть методы для каждого конкретного типа, и это очень сложно поддерживать.
Было бы лучше использовать дизайн, который в первую очередь не требует этого ограничения.
Вы можете упростить свой интерфейс и избежать этой проблемы, полностью избавившись от IServiceResult
interface IServiceResponder {
void CouldNotFindFile();
void CouldNotReadFile();
void ServiceSuccessful();
}
interface IService {
void PerformService(IServiceResponder responseTarget);
}
// Console Client Code:
IService service = new Service();
// this will print the response to the console when it is set
IServiceResponder responder = new ConsoleServiceResponder();
service.PerformService(responder);