Qt 项目架构之三:MVC架构
MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。
- Model(模型)-是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
- View(视图) -是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器) - 是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。
MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。
以 C++ 代码为例,设计英雄(Hero)对战 demo。Hero1 对 Hero2 进行攻击,Hero2 不断掉血,UI 同步更新。主要三个类,分别为 Hero(英雄数据类),HeroView(英雄UI类,如血条)和 HeroController(英雄控制器类,Hero 管理类)。
Hero 类:
#pragma once
class Hero
{
public:
Hero();
~Hero();
//be attacked
void beAttack(int att);
//is dead?
bool dead() { return m_nHp == 0; }
public:
//set no
void setNo(std::string no) { m_sNo = no; }
//get no
std::string getNo() { return m_sNo; }
//set name
void setName(std::string name) { m_sName = name; }
//get name
std::string getName() { return m_sName; }
//get hp
void setHp(int hp) { m_nHp = hp; }
//set hp
int getHp() { return m_nHp; }
//set att
void setAtt(int att) { m_nAtt = att; }
//get att
int getAtt() { return m_nAtt; }
private:
std::string m_sName;//姓名
std::string m_sNo;//游戏场号码
int m_nHp;//血量
int m_nAtt;//攻击力
};
#include "stdafx.h"
#include "Hero.h"
//ctor
Hero::Hero()
{
}
//Destructor
Hero::~Hero()
{
}
void Hero::beAttack(int att)
{
if (att <= 0) throw "Att Number <= 0";//safe check
m_nHp -= att;
m_nHp = m_nHp < 0 ? 0 : m_nHp;//safe check
}
HeroView 类:
#pragma once
class HeroView
{
public:
HeroView();
~HeroView();
//show hero UI data;
void show(string no, string name,int att, int hp);
//show hero dead UI;
void dead(string no, string name);
//show heor winned UI;
void winned(string no, string name);
private:
//Hero* m_hero;
};
#include "stdafx.h"
#include "HeroView.h"
HeroView::HeroView()
{
}
HeroView::~HeroView()
{
}
void HeroView::show(string no,string name, int att, int hp)
{
cout << "Hero info:"<<"(no:"<<no<<",name:"<<name<<",att:"<<att<<",hp:"<<hp<<")" << endl;
}
void HeroView::dead(string no, string name)
{
cout << "Hero Dead:" << "(no:" << no << ",name:"<<name << ")" << endl;
}
void HeroView::winned(string no, string name)
{
cout << "Hero Winned:" << "(no:" << no << ",name:" << name << ")" << endl;
}
HeroController 类:
#pragma once
class HeroController
{
public:
HeroController(string no, string name);
~HeroController();
void setHeroHp(int hp);//set hero hp
void setHeroAtt(int att);//set hero att
void show();//show hero info
void beAttack(int att);//be attacked by hero
void dead();//dead
void winned();//winned
Hero* getHero() { return m_hero; }//get hero
private:
Hero * m_hero;//hero
HeroView * m_heroView;//hero view
};
#include "stdafx.h"
#include "HeroController.h"
HeroController::HeroController(string no, string name)
{
m_heroView = new HeroView();
m_hero = new Hero();
m_hero->setNo(no);
m_hero->setName(name);
}
HeroController::~HeroController()
{
}
void HeroController::setHeroHp(int hp)
{
m_hero->setHp(hp);
}
void HeroController::setHeroAtt(int att)
{
m_hero->setAtt(att);
}
void HeroController::show()
{
m_heroView->show(m_hero->getNo(), m_hero->getName(),m_hero->getAtt(), m_hero->getHp());
}
void HeroController::beAttack(int att)
{
m_hero->beAttack(att);
}
void HeroController::dead()
{
m_heroView->dead(m_hero->getNo(),m_hero->getName());
}
void HeroController::winned()
{
m_heroView->winned(m_hero->getNo(), m_hero->getName());
}
main() 测试:
// ConsoleApplication_C++1.cpp: 主项目文件。
#include "stdafx.h"
using namespace System;
int main()
{
//初始化一个英雄的控制器
HeroController* controller = new HeroController("2017","孟栋");
//设置血量100
controller->setHeroHp(100);
controller->setHeroAtt(40);
//显示一下血量
controller->show();
//初始化第二个英雄的控制器
HeroController* controller2 = new HeroController("2016", "黑魔王");
//设置血量100
controller2->setHeroHp(200);
//设置攻击力20
controller2->setHeroAtt(20);
//显示一下血量
controller2->show();
//hero1 attack hero2
controller2->beAttack(controller->getHero()->getAtt());
//ui更新
controller2->show();
//如果没有dead,就一直攻击
while (!controller2->getHero()->dead())
{
//hero1 attack hero2
controller2->beAttack(controller->getHero()->getAtt());
//ui更新
controller2->show();
}
controller2->dead();
controller->show();
controller->winned();
return 0;
}
控制台输出如下:
Hero info : (no:2017, name : 孟栋, att : 40, hp : 100)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 200)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 160)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 120)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 80)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 40)
Hero info : (no : 2016, name : 黑魔王, att : 20, hp : 0)
Hero Dead : (no : 2016, name : 黑魔王)
Hero info : (no : 2017, name : 孟栋, att : 40, hp : 100)
Hero Winned : (no : 2017, name : 孟栋)