Принцип единой ответственности в чистой архитектуре, объединяющий UseCase в одном UseCaseManager, который может предоставлять UseCase на основе In & Out Object.
Я хочу реализовать принцип Единой Ответственности в своих проектах Доменный уровень (Чистый MVVM).
У меня ок. 200 различных вариантов использования, которые очень сложны в управлении. Сейчас я думаю создать один UseCaseManager, который может предоставить мне необходимый UseCase на основе объекта ввода и вывода.
Я попробовал подход, но это выглядит не очень хорошо. Я привожу пример кода. Пожалуйста, помогите мне, как я могу объединить все UseCases в один UseCaseManager.
UseCase1:
public class ActualUseCase1 extends AsyncUseCase<Object3,Object4> {
public ActualUseCase1(SchedulerProvider schedulerProvider) {
super(schedulerProvider);
}
@Override
public Flowable<Object4> buildUseCaseFlowable(Object3 input) {
return Flowable.just(new Object4());
}
}
UseCase2:
public class ActualUseCase2 extends AsyncUseCase<Object1, Object2> {
public ActualUseCase2(SchedulerProvider schedulerProvider) {
super(schedulerProvider);
}
@Override
public Flowable<Object2> buildUseCaseFlowable(Object1 input) {
return Flowable.just(new Object2());
}
}
UseCaseManager:
public interface UseCaseManager<In, Out> {
<T> T getUseCase(In input, Out output);
}
T могут быть разными UseCase с разными In & Out Object.
UseCaseManagerImpl:
public class UseCaseManagerImpl implements UseCaseManager {
@Override
public Object getUseCase(Object object1, Object object2) {
return null;
}
}
Сейчас это главная проблема, я не в состоянии понять. Как я могу реализовать метод getUseCase.
3 ответа
Я думаю, что вы заново изобретаете абстрактный шаблон фабрики. Google предоставит вам много контента на эту тему...
Сложность в том, как вы решаете, какой подтип создавать и возвращать; это может быть так же просто, как оператор switch, или включать таблицы поиска и т. д. Ключевым моментом является то, что вы изолируете эту логику в одном месте, где вы можете выполнить ее модульное тестирование.
Более важный вопрос - как вы в итоге получаете 200 подклассов?
Хорошо, я получаю представление, что вы хотите что-то вроде системы, в которой для заданного ввода вы получите некоторый вывод. И вы можете иметь 200 таких входов, для которых возможно 200 соответствующих выходов. И вы хотите сделать все это управляемым.
Я попытаюсь объяснить решение, которое я имею в виду. Я новичок в Java и, следовательно, не смогу создавать много кода.
Вы можете реализовать это с помощью шаблона Chain of Responsibility. В этом шаблоне проектирования у вас есть исполнитель заданий (UseCaseManagaer в вашем случае) и несколько заданий (UseCases) для выполнения, которые будут выполняться последовательно, пока одно из них не вернет вывод.
Вы можете создать класс RequestPipeline, который будет выполнять работу. В UseCaseManager вы создаете конвейер один раз и все сценарии использования, которые хотите добавить, используя шаблон Builder, например:
RequestPipeline.add(new UseCase1())
RequestPipeline.add(new UseCase2())...
Когда ввод поступает, вы запускаете RequestPipeline, который будет запускать все добавленные к нему задания, последовательно, один за другим. Если UseCase возвращает значение NULL, то выполняющий работу вызовет следующую строку UseCase в строке, пока не найдет UseCase, который может управлять вводом и выдавать ответ.
Преимущества этого шаблона проектирования:
- Абстракция: RequestPipeline отвечает за выполнение заданий в очереди, но ничего не знает о выполняемых заданиях. С другой стороны, UseCase знает только об обработке своего собственного варианта использования. Это единица сама по себе. Следовательно, принцип единой ответственности удовлетворяется, поскольку оба они независимы друг от друга и могут использоваться повторно всякий раз, когда у нас появляется аналогичное проектное требование позже.
- Легко расширяемый: если вам нужно добавить 10 других вариантов использования, вы можете легко добавить их в RequestPipeline, и все готово.
- Нет переключателя и если-еще. Это само по себе большое достижение. Я люблю Chain of Responsibility по этой самой причине.
- Декларативное программирование: мы просто объявляем, что нам нужно сделать, и оставляем детали того, как это сделать, отдельным подразделениям. Дизайн кода легко понятен новому разработчику.
- Больше контроля: RequestPipeline имеет возможность динамически выбирать работу для запуска во время выполнения.
Ссылка: https://www.google.co.in/amp/s/www.geeksforgeeks.org/chain-responsibility-design-pattern/amp/
Здесь приведен код Java, чтобы вы могли проверить, удовлетворяет ли он вашему варианту использования.
Надеюсь это поможет. Пожалуйста, дайте мне знать, если у вас есть какие-либо сомнения в разделе комментариев.
То, что вы пытаетесь сделать, - это НЕ единственная ответственность, это наоборот.
Единственная ответственность означает
Должна быть одна причина изменить
См. Принцип единой ответственности
То, что вы пытаетесь реализовать, будет обрабатывать все 200 ваших вариантов использования. Таким образом, он будет меняться при изменении варианта использования ». Это смешивание проблем, а не их разделение.
Обычно варианты использования вызываются контроллерами, и обычно контроллер также несет единственную ответственность. Таким образом, контроллер знает, какой вариант использования он должен вызвать. Таким образом, я не вижу необходимости в
UseCaseManager
.
Я предполагаю, что в вашем дизайне есть еще одна проблема, которая ведет к вашей проблеме. Но поскольку у меня нет вашего полного исходного кода, я не могу дать вам никаких дополнительных советов.