MVC模式

模式简介

MVC模式是一种架构模式,它包含三个角色:模型(Model),视图(View)和控制器(Controller)。观察者模式可以用来实现MVC模式,观察者模式中的观察目标就是MVC模式中的模型(Model),而观察者就是MVC中的视图(View),控制器(Controller)充当两者之间的中介者(Mediator)。当模型层的数据发生改变时,视图层将自动改变其显示内容。

模式实现

  • Model:这是数据层,绝大多数的数据都存储在这一层中。Model层不知道关于view或者controller的任何事情,只是返回数据或者更新数据。在web应用中,常用于数据库存储数据。
  • View:这是视图层,用于向用户显示数据。View本身不显示任何数据,而是controller或者model让view显示数据
  • Controller:这是控制层,可以看成是MVC的核心部分。控制器相当于用户和系统之间的一个连接,接受用户的请求,获取用户的输入,是用户控制其他控件的控制器.

在MVC中,Model更新的时候,会以观察者的方式,来通知当前所有的视图;之后视图会根据数据进行相应的显示操作。用户不能通过视图更新数据,只可以通过Controller的方式与Model交互。

代码示例

代码中,Student是元数据,Model存储了一系列的Student的数据。之后通过Controller与Model交互,数据变动时,会立刻通知所有的视图。

#include <iostream>
#include <set>
#include <list>
#include <string>
#include <memory>
#include <cassert>

class Student {
public:

    inline void setName(std::string &name) {
        m_strName = std::move(name);
    }

    inline void setId(std::string &id) {
        m_strId = std::move(id);
    }

    inline void setScore(int socre) {
        if (socre < 0) {
            return;
        }
        m_iScore = socre;
    }

    std::string getName() {
        return m_strName;
    }
    std::string getId() {
        return m_strId;
    }
    int getScore()  {
        return m_iScore;
    }

    bool operator<(const Student &student) const {
        std::cout << m_strId << ", " << student.m_strId << std::endl;
        return m_strId < student.m_strId;
    }
    
private:
    std::string m_strName;
    std::string m_strId;
    int m_iScore;
};

struct cmp {
    bool operator()(const std::shared_ptr<Student>& lt, const std::shared_ptr<Student>& rt) const {
        return lt->getId() < rt->getId();
    }
};

class View {
public:
    View(int id = 0): m_iId(id) {}
    void update(const std::set<std::shared_ptr<Student>, cmp>& students) {
        std::cout << "View " << m_iId << " updates:\n";
        for (const auto& student: students) {
            std::cout << "Id: " << student->getId() 
                      << ", Name: " << student->getName() 
                      << ", Score: " << student->getScore() << std::endl;
        }
    }
private:
    int m_iId;
};

class Model {
public:
    void addStudent(std::string &id, std::string &name, int score) {
        auto it = std::make_shared<Student>();
        it->setId(id);
        it->setName(name);
        it->setScore(score);
        if (m_Students.find(it) == m_Students.end()) {
            m_Students.insert(it);
        }
        notify();
    }
    
    void removeStudent(std::string& id) {
        auto student = std::make_shared<Student>();
        student->setId(id);
        m_Students.erase(student);
        std::cout << "Student size: " << m_Students.size() << std::endl;
        notify();
    }

    void addView(std::shared_ptr<View> view) {
        m_Views.push_back(std::move(view));
    }

    void notify() {
        for (auto& view: m_Views) {
            view->update(m_Students);  // 通知视图做出变化
        }
    }

private:
    std::set<std::shared_ptr<Student>, cmp> m_Students;
    std::list<std::shared_ptr<View>> m_Views;
};

class Controller {
public:

    Controller(Model& model): m_Model(model) {}

    void Insert(std::string &id, std::string &name, int socre) {
        m_Model.addStudent(id, name, socre);
    }
    void Delete(std::string &id) {
        m_Model.removeStudent(id);
    }

    void setModel(Model &model) {
        m_Model = model;
    }

private:
    Model& m_Model;
};


int main() {
    Model model;
    for (int i = 0; i < 3; ++i) {  // 添加三个视图
        model.addView(std::make_shared<View>(i + 1));
    }
    Controller controller(model);
    std::string name, id;
    std::cout << "----------------Insert Data----------------\n";
    id = "001";
    name = "Tom";
    controller.Insert(id, name, 100);
    std::cout << "----------------Insert Data----------------\n";
    id = "002";
    name = "Sam";
    controller.Insert(id, name, 80);
    std::cout << "----------------Insert Data----------------\n";
    id = "003";
    name = "Amy";
    controller.Insert(id, name, 90);
    std::cout << "----------------Insert Data----------------\n";
    id = "004";
    name = "Lily";
    controller.Insert(id, name, 90);
    std::cout << "----------------Delete Data----------------\n";
    id = "003";
    controller.Delete(id);

    return 0;
}

输出结果:

----------------Insert Data----------------
View 1 updates:
Id: 001, Name: Tom, Score: 100
View 2 updates:
Id: 001, Name: Tom, Score: 100
View 3 updates:
Id: 001, Name: Tom, Score: 100
----------------Insert Data----------------
View 1 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
View 2 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
View 3 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
----------------Insert Data----------------
View 1 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
View 2 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
View 3 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
----------------Insert Data----------------
View 1 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
Id: 004, Name: Lily, Score: 90
View 2 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
Id: 004, Name: Lily, Score: 90
View 3 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 003, Name: Amy, Score: 90
Id: 004, Name: Lily, Score: 90
----------------Delete Data----------------
Student size: 3
View 1 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 004, Name: Lily, Score: 90
View 2 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 004, Name: Lily, Score: 90
View 3 updates:
Id: 001, Name: Tom, Score: 100
Id: 002, Name: Sam, Score: 80
Id: 004, Name: Lily, Score: 90
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值