Почему в шаблоне проектирования MVC именно 3 компоненты?

Мне понятно, зачем выделяют отдельно View.
1. При изменениях интерфейса (но не логики) не затрагиваются классы, отвечающие за логику приложения
2. Для GUI невозможно написать тесты, поэтому выделив код, отвечающий за пользоватиелский интерфейс в отдельные классы, можно применить тесты к Model и Controller
3. В теории упрощаем портирование приложения под другой GUI framework так как, придется переписывать только View

Но мне не понятно зачем разделять Model и Controller.
Ведь остальная часть приложения - это некоторые данные плюс интерфейс к ним. Это вполне укладывается в парадигму ООП. Данные - это private члены класса, интерфейс - это public. Читать и менять данные можно только через Controller. Данные и есть Model.

В чем я заблуждаюсь? С чем я столкнусь, если Model и Controller будут объединены в одну сущность. Что я приобрету, если попытаюсь таки разделить Model и Controller на разные сущности, которые будут взаимодействовать через некий интерфейс? Хотя как их делить?
  • Вопрос задан
  • 2528 просмотров
Пригласить эксперта
Ответы на вопрос 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
То что вы описываете - подход с использованием толстых контроллеров. Откройте для себя дивный мир Service-Oriented Architecture. Вообще как, модели, они же доменные модели, это просто представление данных. За сохранение данных и их обработку, валидацию и т.д. отвечают сервисы. Контроллеры так же можно представлять в виде сервисов, и из задача будет только проверка, имеет ли пользователь доступ к данной операции, что собственно нужно сделать и т.д. Таким образом контроллер может вообще не иметь понятия о том, где хранятся данные, как они обрабатываются... Он просто смотрит что пользователь может сохранять данные, передает данные пользователя сервису, тот сохраняет....

Короче как-то так.

Пример модели:
class User
{
    private $id;
    private $email;
    private $password;
    private $enabled;

    public function getId() {...}
    public function getEmail() {...}
    public function setEmail($email) {...}
    public function getPassword() {...}
    // за хэширование пароля отвечает сервис, модель ничего об этом знать не должна.    
    public function setPassword($password) {...} 
    public function isActive() {}
    public function activate() {}
}


пример контроллера
/**
 * @Route("/users")
 * @Method("POST")
 */
public function createUserAction(Request $request) {
    if (!$this->get('security.context')->isGranted('ROLE_ADMIN')) {
        throw new AccessDeniedException();
    }

    $user = new User();
    $form = $this->createForm(new UserForm(), $user);
    $form->bindRequest($request);
    if (!$form->isValid()) {
        // save errors to session, redirect     
        return $this->redirecti(...);
    }
 
    $user = $form->getData();
    $this->get('app.user_manager')->createUser($user);

    return $this->redirect();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы