赞
踩
本文结合一个小案例,讲解MVC、MVP和MVVE在Unity中的相关应用
MVC是一种软件架构模式,全称为Model-View-Controller(模型-视图-控制器)。它将应用程序分为三个主要部分:模型(Model),视图(View)和控制器(Controller)。
模型(Model):模型表示数据模型,实现对数据的增删查改,保存加载等功能
视图(View):视图负责展示模型的数据给用户,并且给用户提供交互功能
控制器(Controller):控制器负责处理用户的输入和操作。它接收用户输入,并根据输入更新模型和视图。控制器将用户的请求转发给模型进行处理,并将结果返回给视图进行展示。
MVC的设计目标是将应用程序的逻辑分离,使得模型、视图和控制器能够独立地进行开发和维护。这种分离提高了代码的可读性、可扩展性和可维护性,同时也方便了团队合作开发。
在Unity中,MVC框架主要用在UI页面中。
这里我用一个简单的UI页面来进行展示,面板上有三个元素,一个Text负责显示数字,两个Button分别实现数字加一和减一,通过代码可以看到,我们将MVC三个部分糅合到一个脚本文件中,注释标注了每一部分对应的MVC操作
public class TestPanel : MonoBehaviour { //View public Text txtNum; public Button btnAdd; public Button btnMinus; //Model private int num; void Start() { //Model num = PlayerPrefs.GetInt("Num", 100); //View btnAdd.onClick.AddListener(Add); btnMinus.onClick.AddListener(Minus); } //Model private void Add() { num = PlayerPrefs.GetInt("Num", 100); num++; PlayerPrefs.SetInt("Num",num); UpdateInfo(); } private void Minus() { num = PlayerPrefs.GetInt("Num", 100); num--; PlayerPrefs.SetInt("Num",num); UpdateInfo(); } //View private void UpdateInfo() { txtNum.text = PlayerPrefs.GetInt("Num", 100).ToString(); } }
创建三个脚本,分别对应Model,View,Controller,注意View和Controller需要挂载到Panel上,我使用了自建的EventCenter事件中心类来实现通知功能(可以自行实现,此处不予贴出)
/// <summary> /// Model类,负责数据的处理,加载和保存 /// </summary> public class TestModel { private int num; public int Num => num; private event UnityAction<TestModel> updateEvent; private static TestModel instance = new TestModel(); public static TestModel Instance => instance; private TestModel() { Init(); } private void Init() { num = PlayerPrefs.GetInt("Num", 100); } public void Add() { num++; //改变过后保存 SaveData(); } public void Minus() { num--; //改变过后保存 SaveData(); } // 保存 public void SaveData() { //把这些数据内容 存储到本地 PlayerPrefs.SetInt("Num",num); UpdateInfo(); } public void AddEventListener(UnityAction<TestModel> function) { updateEvent += function; } public void RemoveEventListener(UnityAction<TestModel> function) { updateEvent -= function; } //通知外部更新数据的方法 private void UpdateInfo() { //找到对应的 使用数据的脚本 去更新数据 if( updateEvent != null ) { updateEvent(this); } EventCenter.GetInstance().EventTrigger<TestModel>("更新数据", this); } }
/// <summary>
/// 视图类,负责显示UI元素,提供交互按钮
/// </summary>
public class TestView : MonoBehaviour
{
public Text txtNum;
public Button btnAdd;
public Button btnMinus;
//提供面板更新的相关方法给外部
public void UpdateInfo( TestModel data)
{
txtNum.text = data.Num.ToString();
}
}
/// <summary> /// Controller类,负责处理Model和View之间的交互 /// </summary> public class TestController : MonoBehaviour { private TestView testView; private static TestController instance = null; public static TestController Instance => instance; private void Start() { //得到View和Controller脚本 instance = GetComponent<TestController>(); testView = GetComponent<TestView>(); //第一次的界面更新 testView.UpdateInfo(TestModel.Instance); //界面事件的监听 来处理对应的业务逻辑 testView.btnAdd.onClick.AddListener(ClickAdd); testView.btnMinus.onClick.AddListener(ClickMinus); //告知数据模块 当更新时 通知哪个函数做处理 TestModel.Instance.AddEventListener(UpdateView); } //通知Model进行num的增减 private void ClickAdd() { TestModel.Instance.Add(); } private void ClickMinus() { TestModel.Instance.Minus(); } //界面的更新 private void UpdateView( TestModel data ) { if( testView != null ) { testView.UpdateInfo(data); } } //事件监听有加就有减,防止空引用 private void OnDestroy() { TestModel.Instance.RemoveEventListener(UpdateView); } }
运行测试,成功实现功能
不使用MVC时,所有逻辑在一个脚本中完成,耦合度增加,可重复性差(比如我要把num的类型从int改为float,那么几乎所有方法都要进行修改,而MVC框架中只需要修改Model的部分)。
但是,使用MVC框架后,肉眼可见代码量的增加,原本40行就能实现的代码,暴增到100多行,同时结构变得更复杂,代码可读性变差。在实际开发中需要根据需求使用或不使用MVC
MVP框架是一种基于MVC模式的软件架构模式,全称为Model-View-Presenter(模型-视图-呈现器)。它在MVC模式的基础上做了一些改进,旨在进一步分离视图和模型,并引入了呈现器(主持人)(Presenter)来处理视图和模型之间的交互。
MVP框架的主要组成部分包括:
模型(Model):模型代表应用程序的数据和业务逻辑。
视图(View):视图负责展示模型的数据给用户。
呈现器(Presenter):呈现器是MVP框架的新增组件,它充当了控制器的角色。呈现器负责处理用户的输入和操作,并根据输入更新模型和视图。呈现器将用户的请求转发给模型进行处理,并将结果返回给视图进行展示。
在MVC案例中,我们在Controller中将Model传给了View进行处理,这就造成了View对Model的依赖,为了实现彻底的分离,我们需要将数据更新操作放到Controller中,这就是MVP
Model类与MVC相同,只是将修改数据的操作UpdateInfo从Model中转移到了Presenter中,可以自行测试
/// <summary>
/// 视图类,负责显示UI元素,提供交互按钮
/// </summary>
public class TestView_MVP : MonoBehaviour
{
public Text txtNum;
public Button btnAdd;
public Button btnMinus;
//不再提供面板更新的相关方法给外部
// public void UpdateInfo( TestModel data)
// {
// txtNum.text = data.Num.ToString();
// }
}
/// <summary> /// Presenter类,负责处理Model和View之间的交互 /// </summary> public class TestPresenter : MonoBehaviour { private TestView_MVP testView; private static TestController instance = null; public static TestController Instance => instance; private void Start() { //得到View和Controller脚本 instance = GetComponent<TestController>(); testView = GetComponent<TestView_MVP>(); //第一次的界面更新 //testView.UpdateInfo(TestModel.Instance); UpdateInfo(TestModel.Instance); //界面事件的监听 来处理对应的业务逻辑 testView.btnAdd.onClick.AddListener(ClickAdd); testView.btnMinus.onClick.AddListener(ClickMinus); //告知数据模块 当更新时 通知哪个函数做处理 TestModel.Instance.AddEventListener(UpdateInfo); } //通知Model进行num的增减 private void ClickAdd() { TestModel.Instance.Add(); } private void ClickMinus() { TestModel.Instance.Minus(); } //界面的更新 // private void UpdateView( TestModel data ) // { // if( testView != null ) // { // testView.UpdateInfo(data); // } // } //自己提供修改方法 而不是在Model里去更新 private void UpdateInfo(TestModel data) { if (testView != null) { //roleView.UpdateInfo(data); //直接在P中得到V界面的控件 进行修改 断开V和M的联系 testView.txtNum.text = data.Num.ToString(); } } //事件监听有加就有减,防止空引用 private void OnDestroy() { TestModel.Instance.RemoveEventListener(UpdateInfo); } }
MVP中的Presenter完全断绝View和Model的耦合,实现进一步的分离
MVVM是一种软件架构模式,全称为Model-View-ViewModel(模型-视图-视图模型)。它是在MVC和MVP模式的基础上发展出来的,旨在进一步分离视图和模型,并引入了视图模型(ViewModel)来处理视图和模型之间的交互。
MVVM框架的主要组成部分包括:
模型(Model):模型代表应用程序的数据和业务逻辑。
视图(View):视图负责展示模型的数据给用户。
视图模型(ViewModel):视图模型是MVVM框架的新增组件,它充当了控制器或呈现器的角色。视图模型负责将模型的数据转换为视图可以理解和展示的形式,并处理视图的用户交互。它封装了视图和模型之间的通信和数据绑定逻辑。
说人话就是UI页面和数据绑死,修改UI元素会自动修改数据,在代码中修改数据也会自动更新UI显示
MVVM主要用于窗体应用开发,与游戏开发不是很搭配,而且Unity中实现MVVM非常复杂,这里就不实现了,感兴趣的可以去搜索相关的第三方插件
MVC思想最初来自网页和软件开发,并不是为了游戏开发而生,在游戏开发中主要用在大型商业游戏中,小项目使用反而会带来更多麻烦,请酌情使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。