Что такое паттерн MVC?

«Что такое паттерн MVC?» — вопрос из категории Паттерны, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

MVC (Model-View-Controller) — это архитектурный паттерн, разделяющий ответственность приложения на три взаимосвязанных компонента для улучшения структуры и тестируемости, особенно в контексте приложений с пользовательским интерфейсом.

Компоненты в контексте C++/Qt (как пример фреймворка):

  1. Model: Управляет данными и бизнес-логикой. Уведомляет View об изменениях (часто через паттерн Наблюдатель).
  2. View: Отображает данные из Model (UI). Получает пользовательский ввод и передает его Controller'у.
  3. Controller: Обрабатывает ввод от пользователя (например, нажатия кнопок), взаимодействует с Model для её обновления.

Упрощённый пример на C++ (без фреймворка):

#include <iostream>
#include <string>

// Model
class TaskModel {
    std::string description;
    bool isCompleted{false};
public:
    void setDescription(const std::string& desc) { description = desc; }
    void setCompleted(bool completed) { isCompleted = completed; }
    std::string getDescription() const { return description; }
    bool getCompleted() const { return isCompleted; }
};

// View
class TaskView {
public:
    void displayTask(const std::string& desc, bool completed) const {
        std::cout << "Task: " << desc 
                  << " [" << (completed ? "X" : " ") << "]" << std::endl;
    }
};

// Controller
class TaskController {
    TaskModel& model;
    TaskView& view;
public:
    TaskController(TaskModel& m, TaskView& v) : model(m), view(v) {}
    void setTaskCompleted(bool status) {
        model.setCompleted(status);
        updateView();
    }
    void updateView() const {
        view.displayTask(model.getDescription(), model.getCompleted());
    }
};

// Использование
int main() {
    TaskModel model;
    model.setDescription("Implement MVC pattern");
    TaskView view;
    TaskController controller(model, view);

    controller.updateView(); // Task: Implement MVC pattern [ ]
    controller.setTaskCompleted(true); // Task: Implement MVC pattern [X]
    return 0;
}

Преимущества в C++ проектах:

  • Разделение ответственности: UI-код (View) отделен от логики (Model).
  • Упрощение тестирования: Model и бизнес-логику можно тестировать без GUI.
  • Гибкость: Можно создать несколько разных View (консольное, графическое) для одной Model.

Сложности:

  • Может добавлять избыточность для простых утилит.
  • В чистом C++ реализация механизма наблюдения (Model->View) требует дополнительного кода (например, использование signals/slots в Qt или собственной реализации Observer).