Я экспериментирую с Робертом "Дядя Боб" Мартина Чистая архитектура, чтобы использовать его в будущем проекте. Это веб-приложение на основе Spring MVC.
Одна особенность состоит в том, что, как только пользователь входит в систему, на его домашней странице появляются различные разделы в зависимости от его типа пользователя.
В моем маленький прототип, у меня все работает нормально, но я не доволен своим решением. В частности, где я должен определить, с каким типом пользователя я имею дело?
Я пытаюсь также следовать принципу единой ответственности, поэтому я создал абстрактный ViewHomePageUseCase, который имеет дело с общими разделами на домашней странице каждого пользователя. , У меня также есть ViewUserType1HomePageUseCase, et c., Для определенных c пользовательских типов, которые расширяют базовый класс.
Хотя в настоящее время в моем Spring @Controller у меня есть что-то вроде этого:
@RequestMapping(value = {"/home"}, method = RequestMethod.GET)
public String getHomePage(Model model) {
ViewHomePageResponseModel response;
String userId = "test";
int userType = this.getUserProfileUseCase.getUserType(userId);
switch(s) {
case 1:
response = useCaseFactory.viewUserType1_HomePageUseCase().getHomePage(userId);
break;
case 2:
response = useCaseFactory.viewUserType2_HomePageUseCase().getHomePage(userId);
break;
default:
response = useCaseFactory.viewSimpleHomePageUseCase().getHomePage(userId);
}
HomePageViewModel viewModel = presenter.presentHomePage(response);
model.addAttribute("viewModel", viewModel);
return "home";
}
хотя мне и не нравится этот контроллер, так как в нем есть бизнес-логика c.
В более ранней версии моего прототипа я пытался поставить «определить тип пользователя» функция в самом сценарии использования, затем делегирование в правильный вариант использования. Хотя это сработало, мне это тоже не понравилось.
Одна вещь, которая мне нравится в моей текущей версии, это наличие нескольких классов ViewHomePageUseCase через наследование, но я не знаю, как и где выбрать вариант использования в зависимости от типа пользователя.
Надеюсь, у меня все понятно!
Любая помощь приветствуется!
Крис
ОБНОВЛЕНИЕ -
В конечном итоге я создал отдельные варианты использования для каждой домашней страницы, а также вариант использования для определения, какая домашняя страница необходима. Я также использую фабрику для создания экземпляра сценария использования. Каждый вариант использования домашней страницы просто получает данные, которые нужны конкретной домашней странице. Тогда Spring Controller упрощается:
@Controller
public class HomeController {
private IUseCaseFactory useCaseFactory;
@Autowired
public HomeController(IUseCaseFactory useCaseFactory) {
this.useCaseFactory = useCaseFactory;
}
@RequestMapping(value = {"/home"}, method = RequestMethod.GET)
public String getHomePage(Model model) {
String userId = "steven"; // User Type 2
// hardcoded userId's are used in the GetHomePageUseCase class.
IHomePagePresenter presenter = this.useCaseFactory.getHomePageUseCase().getHomePage(userId);
HomePageViewModel viewModel = presenter.presentHomePage();
model.addAttribute("viewModel", viewModel);
return "home";
}
}
Мой GetHomePageUseCase, который решает, какая домашняя страница необходима, выглядит примерно так:
public class GetHomePageUseCase implements IViewHomePageUseCase {
private IUseCaseFactory useCaseFactory;
public GetHomePageUseCase(IUseCaseFactory useCaseFactory) {
this.useCaseFactory = useCaseFactory;
}
@Override
public IHomePagePresenter getHomePage(String userId) {
IHomePagePresenter presenter;
//temporary
//TODO - once users are in place, rewrite this function.
String userRole;
switch(userId) {
case "chris":
userRole = "UserType1";
break;
case "steven":
userRole = "UserType2";
break;
default:
userRole = "Public";
break;
}
switch(userRole) {
case "UserType1":
presenter = useCaseFactory.viewUserType1HomePageUseCase().getHomePage(userId);
break;
case "UserType2":
presenter = useCaseFactory.viewUserType2HomePageUseCase().getHomePage(userId);
break;
default:
presenter = useCaseFactory.viewPublicHomePageUseCase().getHomePage(userId);
break;
}
return presenter;
}
}
Я до сих пор не уверен в этом подходе , Хотя он чище, чем в первой версии, я не совсем доволен им.
Более общий вопрос: когда у вас есть веб-страница (в данном случае), ее функции зависят от какой-либо роли пользователя или разрешений Как я могу включить эти права пользователей в подход чистой архитектуры? Например, на другой странице (моя страница просмотра) отображаемые основные данные c одинаковы для всех пользователей, но в зависимости от роли / разрешений пользователя пользователь может редактировать, удалять и т. Д. c. в противном случае эти кнопки даже не отображаются. В этом случае (для моей страницы просмотра) у меня есть логические флаги, такие как showEditButton, которые будут установлены с помощью варианта использования, а сам код страницы просмотра просто проверяет флаг, чтобы показать или скрыть кнопку. Это правильный способ сделать это в чистой архитектуре?
Еще раз спасибо !!
Крис