最近因为要用c++实现mvvm。对这些架构(MVC, MVP, MVVM)雨里雾里。
看了一些文章介绍,总体觉得mvvm除了前后端分离,解耦,最大的特点是数据的双向绑定,即当view改变时,可以通过viewmodel自动改变model,当model改变时,也可以通过viewmodel自动改变view。
如果理解偏差,前辈们多多指点。感谢!
实现思路:采用回调函数的方法:即在view初始化的时候bind一个修改view自身数据的function。 同样在初始化model的时候,bind一个修改model自身的function。然后在viewModel里面模拟修改view和model。在修改view的时候,调用model的回调函数,在修改model的时候,调用view的回调函数。
其实:感觉实现方法很多,比如我直接全部用static调用过去也可以。如果理解偏差,前辈们多多指点。感谢!
#include <iostream>
#include <functional>
#include <map>
#include <string>
//只测试绑定一个数据,name=xxx
std::map<std::string, std::function<void(std::string)> > viewChange;
std::map<std::string, std::function<void(std::string)> > modelChange;
std::string properName = "name";
class View
{
public:
explicit View(std::string properName, std::string data) : _data(data), _properName(properName) {
viewChange[_properName] = std::bind(&View::setData, this, std::placeholders::_1);
}
void ViewChange(std::string data)
{
modelChange[_properName](data);
}
void printViewData() {
std::cout << this->_data << std::endl;
}
private:
std::string _data;
std::string _properName;
void setData(std::string data){
this->_data = data;
}
};
class Model
{
public:
explicit Model(std::string properName, std::string data) : _data(data), _properName(properName){
modelChange[_properName] = std::bind(&Model::setData, this, std::placeholders::_1);
}
void ModelChange(std::string data){
viewChange[_properName](data);
}
void printModelData(){
std::cout << this->_data << std::endl;
}
private:
std::string _data;
std::string _properName;
void setData(std::string data){
this->_data = data;
}
};
class ViewModel
{
public:
explicit ViewModel() : _model("name", "zhjwangModel"), _view("name", "zhjwangView"){}
void changeModel(std::string data)
{
_model.ModelChange(data);
}
void changeView(std::string data){
_view.ViewChange(data);
}
private:
Model _model;
View _view;
};
int main()
{
//一开始会改变map中的函数绑定,因为我们都是在初始化的时候做的std::bind,而ViewModel中也要初始化两个对象,所以一开始std::bind的是ViewModel中的两个对象。后面又会改变,所以写在前面
ViewModel viewmodel;
auto view = View(properName, "zhjwang");
view.printViewData();
viewmodel.changeModel("laowang"); //模拟model改变时,通知到ViewModel
view.printViewData();
auto model = Model(properName, "aaa");
model.printModelData();
viewmodel.changeView("bbb"); //模拟view改变时,通知到model
model.printModelData();
return 0;
}