Я экспериментирую с чистой архитектурой Роберта «Дяди Боба» Мартина, чтобы использовать ее в предстоящем проекте. Это веб-приложение на основе Spring MVC.
Одна из особенностей заключается в том, что после входа пользователя в систему на его домашней странице появляются различные разделы в зависимости от типа пользователя.
В моем маленьком прототипе все работает нормально, но я не удовлетворен своим решением. В частности, где я должен определить, с каким типом пользователя я имею дело?
Я также пытаюсь следовать принципу единой ответственности, поэтому я создал абстрактный ViewHomePageUseCase, который имеет дело с общими разделами на всех домашних страницах. У меня также есть ViewUserType1HomePageUseCase и т. д. для определенных типов пользователей, которые расширяют базовый класс.
Хотя в настоящее время в моем 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";
}
хотя мне не нравится этот контроллер, так как в нем есть бизнес-логика.
В более ранней версии моего прототипа я пытался поместить функцию «определить тип пользователя» в сам вариант использования, а затем делегировать ее правильному варианту использования. Хотя это сработало, мне это тоже не понравилось.
В моей текущей версии мне нравится иметь несколько классов ViewHomePageUseCase через наследование, но я не понимаю, как и где выбрать вариант использования в зависимости от типа пользователя.
Я надеюсь, что я ясно!
Любая помощь приветствуется!
Крис
ОБНОВИТЬ --
В итоге я создал отдельные варианты использования для каждой домашней страницы, а также вариант использования для принятия решения о том, какая домашняя страница нужна. Я также использую factory для создания экземпляра варианта использования. Каждый вариант использования домашней страницы просто получает данные, необходимые для конкретной домашней страницы. Контроллер Spring затем упрощается:
@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;
}
}
Я все еще не уверен в этом подходе. Хотя он чище, чем первая версия, я им не совсем доволен.
Более общий вопрос: когда у вас есть веб-страница (в данном случае), функции которой зависят от какой-либо роли или разрешений пользователя, как мне учесть эти разрешения пользователя в подходе чистой архитектуры? Например, на другой странице (моя страница просмотра) основные отображаемые данные одинаковы для всех пользователей, но в зависимости от роли/разрешений пользователя пользователь может иметь возможность редактировать, удалять и т. д., в противном случае эти кнопки недоступны. даже отображается. В этом случае (для моей страницы просмотра) у меня есть логические флаги, такие как showEditButton, которые будут установлены с помощью варианта использования, а сам код страницы просмотра просто проверяет флаг, чтобы показать или скрыть кнопку. Это правильный способ сделать это в чистой архитектуре?
Спасибо еще раз!!
Крис