MVC模型(C++)

MVC模型是(model模型 view视图 controller控制器)是一种软件设计的框架模式,它采用model-view-controller的方法把业务逻辑,数据与视图显示分离,把众多的业务逻辑集合在一个部件里。当然这样并不能让我们理解它,简单的说,就是一种把数据模型,视图显示与人机交互三者分离开的一种编程方式。

为什么要引入MVC模型呢? 

(1)可以使同一个程序使用不同的表现形式,如果控制器反馈给模型的数据发生了变化,那么模型将及时通知有关的视图,视图会对应的刷新自己所展现的内容

(2)因为模型是独立于视图的,所以模型可复用,模型可以独立的移植到别的地方继续使用

(3)前后端的代码分离,使项目开发的分工更加明确,程序的测试更加简便,提高开发效率

其实控制器的功能类似于一个中转站,会决定调用那个模型去处理用户请求以及调用哪个视图去呈现给用户

在实现这个程序之前,有一点需要先给大家提前讲解一下。因为我们已经知道,这里面最少要自定义三个头文件,那么这三个头文件该如何互相去引用呢?

示例:

/A.h
#ifndef A_H
#define A_H
class A{
    B* b;
};
#endif

A.cpp
#include"A.h"
*********
*********

B.h
#ifndef B_H
#define B_H
class B{
    A* a;
};
#endif

/B.cpp
#include"B.h"
*********
*********

假设现在有两个头文件需要相互引用,我们该如何去引用呢?

错误示范: 

/A.h
#ifndef A_H
#define A_H
#include"B.h"
class A{
    B* b;
};
#endif


A.cpp
#include"A.h"
*********
*********

B.h
#ifndef B_H
#define B_H
#include"A.h"
class B{
    A* a;
};
#endif

/B.cpp
#include"B.h"
*********
*********

正确示范:

/A.h
#ifndef A_H
#define A_H
class B;
class A{
    B* b;
};
#endif


A.cpp
#include"A.h"
#include"B.h"
*********
*********

B.h
#ifndef B_H
#define B_H
class A;
class B{
    A* a;
};
#endif

/B.cpp
#include"A.h"
#include"B.h"
*********
*********

好了,那么下面我们用一个简单的程序来说明:

controller 控制台

Controller.h
#pragma once
class Model;
class View;
class Controller{
private:
	Model* model;//控制数据
	View* view;
public:
	Controller();
	~Controller();
	void SetModel(Model* pm);
	void SetView(View* pv);
	void Run();
	void Now();
	void Nextmonth();
	void Prevmonth();
	void Nextyear();
	void Prevyear();
};



//controller.cpp
#include"Controller.h"
#include<iostream>
using namespace std;
#include"Model.h"
#include"View.h"
Controller::Controller() {
	model = nullptr;
	view = nullptr;
}
Controller::~Controller() {}
void Controller::SetModel(Model* pm){
	model = pm;
}
void Controller::SetView(View* pv){
	view = pv;
}
void Controller::Run() {
	int select = 0;
	do {
		select = view->Menum();
		switch (select) {
		case 0:break;
		case 1:Nextmonth(); break;
		case 2:Prevmonth(); break;
		case 3:Nextyear(); break;
		case 4:Prevyear(); break;
		case 5:Now(); break;
		default:printf("input error\n");
		}
	} while (select!=0);
}
void Controller::Now(){
	model->Now();
}
void Controller::Nextmonth() {
	model->Nextmonth();
}
void Controller::Prevmonth() {
	model->Prevmonth();
}
void Controller::Nextyear(){
	model->Nextyear();
}
void Controller::Prevyear() {
	model->Prevyear();
}

 view视图

/view.h
#pragma once
class Model;
class View {
private:
	Model* model;
public:
	View();
	int Menum();//打印菜单
	void Print(int year,int month,int mday,int oneweek,int mtotal)const;
	void Event();
	void SetModel(Model* pm);
};


view.cpp
#include"Model.h"
#include"View.h"
#include<iostream>
using namespace std;
View::View() {
	model = nullptr;
}
void View::Event() {
	Print(model->Getyear(), model->Getmonth(), model->Getmday(), model->Getweek(),model->Getmdays());
}
void View::SetModel(Model* pm) {
	model = pm;
}
int View::Menum() {
	printf("*********************欢迎进入日历打印系统**************************************\n");
	printf("**************************1、下一个月******************************************\n");
	printf("**************************2、上一个月******************************************\n");
	printf("**************************3、下一个年******************************************\n");
	printf("**************************4、上一个年******************************************\n");
	printf("**************************5、当前月份******************************************\n");
	int n ;
	printf("*************************请输入你的选择****************************************\n");
	cin >> n;
	return n;
}//打印菜单
void View::Print(int year, int month, int mday, int oneweek, int mtotal) const{
	int n = mtotal + oneweek;
	int d = 1;
	printf("%d年%d月%d日\n",year,month,mday);
	printf("  Sun Mon Tru Sew Thr Fri Set\n");
	for (int i = 0; i < n;i++) {
		if (i < oneweek) {
			printf("    ");
		}
		else {
			printf("%4d", d++);
		}
		if ((i+1)%7==0) printf("\n");
	}
	printf("\n");
}

model模型

model.h
#pragma once
class View;
class Model {
private:
	View* view;
public://别的类里会调用
	int Getyear()const;
	int Getmonth()const;
	int Getmday()const;
	int Getweek()const;
	int Getmdays()const;
private:
	int year;
	int month;
	int mday;
	int curweek;
	int oneweek;
	int mdays;
	static bool Is_Leap(int y);
	static int GetYM(int y,int m);
	static int Get_week(int y,int m,int d=1);
public:
	Model();
	~Model();
	void SetView(View* pv);
	void Now();
	void Nextmonth();
	void Prevmonth();
	void Nextyear();
	void Prevyear();
};



model.cpp
#include"View.h"
#include"Model.h"
#include<ctime>
bool Model::Is_Leap(int y) {
	return (y % 4 == 0 && y % 100 == 0) || (y % 400 == 0);
}
int Model::GetYM(int y, int m) {//获取当前月份有多少天
	const static int day[] = {29,31,28,31,30,31,30,31,31,30,31,30,31};
	if (m == 2 && Is_Leap(y)) {
		m = 0;
	}
	return day[m];
}
int Model::Get_week(int y, int m,int d) {
	//return (d +1) % 7;
	int c = y / 100;
	int y1 = y % 100;
	int m1 = m;
	
	if (m==1||m==2) {
		m1 += 12;
	}
	return (y1 + y1 / 4 + c / 4 - 2 * c + 26 * (m1 + 1) / 10 + d - 1) % 7;
}
Model::Model():year(1),month(1),mday(1),curweek(1),oneweek(1),mdays(1) {
	//Now();//这里是初始化后已经调用一次展示函数了
	view = nullptr;
}
Model::~Model(){}
int Model::Getyear()const {
	return year;
}
int Model::Getmonth()const {
	return month;
}
int Model::Getmday()const {
	return mday;
}
int Model::Getweek()const {
	return oneweek;
}
int Model::Getmdays()const {
	return mdays;
}
void Model::SetView(View* pv) {
	view = pv;
}
void Model::Now(){
	time_t t;
	tm tmp;
	time(&t);
	localtime_s(&tmp,&t);
	year = tmp.tm_year + 1900;
	month = tmp.tm_mon + 1;
	mday = tmp.tm_mday;
	curweek = tmp.tm_wday;
	mdays = GetYM(year,month);
	oneweek = (mday - 1 - curweek) % 7;//Get_week(year,month,mday,curweek);
	view->Event();
}
void Model::Nextmonth(){
	if (++month > 12) {
		year += 1;
		month = 1;
	}
	mday = 1;
	mdays = GetYM(year,month);
	oneweek = Get_week(year,month,mdays);
	view->Event();
}
void Model::Prevmonth(){
	if (--month > 12) {
		year -= 1;
		month = 12;
	}
	mday = 1;
	mdays = GetYM(year, month);
	curweek = oneweek =Get_week(year, month,mdays);
	view->Event();
}
void Model::Nextyear(){
	year += 1;
	mday = 1;
	mdays = GetYM(year, month);
	curweek = Get_week(year,month,mdays);
	oneweek = Get_week(year, month,mdays);
	view->Event();
}
void Model::Prevyear(){
	if (--year < 1)return;
	mdays = GetYM(year, month);
	curweek = Get_week(year, month,mdays);
	oneweek = Get_week(year, month,mdays);
	view->Event();
}

main主函数

#include<iostream>
using namespace std;
#include"Controller.h"
#include"Model.h"
#include"View.h"
//时间的规律真的太难找了,所以不会,哈哈哈哈
class Client {
public:
	Client() {
		contr.SetModel(&model);
		contr.SetView(&view);
		model.SetView(&view);
		view.SetModel(&model);
	}
	void run() {
		contr.Run();
	}
private:
	Model model;
	Controller contr;
	View view;
};
int main() {
	Client Cli;
	Cli.run();
	return 0;
}

测试用例:

 


版权声明:本文为qq_48757526原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。