在做这个游戏之初始,对框架还是没啥概念的, 随着工程的越来越大,我才理解,高复用,耦合,内聚这些极抽象的概念。
个人认为这框架还是非常广泛而经典的,虽然游戏的代码都是我写的,但我仍体会到这个框架对团队协作非常的有利,各个层级各做各的,互不相干,但又受到统一的规范管理,多好。。
正题,先百度一波:
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中
通俗的理解就是
(view)视图就是来显示给用户的,同时视图被玩家控制,接受玩家的输入,例如:游戏里的UI。
(Model)模型用于保存数据,游戏里的状态会保存在模型里,例如: 地图的数据,生成的物体,关卡等等。
(Controller)控制器作用可认为是一个中间层,可以控制视图,也可以控制模型,也是个比较抽象的概念。
举例:玩家装备枪 ,来说明一个工作循环过程:
实际写代码的时候,不明白为什么要加个控制器作为中间层,视图直接操作模型数据不就可以了吗,看起来是那么回事,那先来看MVC以字典存储的三层结构
//存储MVC
//名字---模型
public static Dictionary<string, Model> Models = new Dictionary<string, Model>();
//名字---视图
public static Dictionary<string, View> Views = new Dictionary<string, View>();
//事件名字---控制器类型
public static Dictionary<string, Type> CommandMap = new Dictionary<string, Type>();
可以看到控制器是以Type类存的,emmm,好像还看不出什么
那再看他是怎么执行命令的
//发送事件
public static void SendEvent(string eventName, object data = null)
{
//控制器响应事件
if (CommandMap.ContainsKey(eventName))
{
Type t = CommandMap[eventName];
Controller c = Activator.CreateInstance(t) as Controller;
//控制器执行
c.Execute(data);
}
//视图响应事件
foreach (View v in Views.Values)
{
if (v != null && v.AttentionEvents.Contains(eventName))
{
//视图响应事件
v.HandleEvent(eventName, data);
}
}
}
对,Controller c = Activator.CreateInstance(t) as Controller;这里可以看出这个类是动态实例化的,嗯,没错,执行完后就会被回收。把逻辑处理写控制器里面(在某个网站上看到这个的,顿然觉悟),有对应的命令时就实例类,用完即丢。这里我们的分工就很明确了,视图类就专门处理你的视图显示,什么复杂的逻辑就别管了,让控制器来,模型就老实的存好数据,发发消息就行。从此,程序解耦,大大降低了类之间的耦合度。
OK现在我们就把这三个抽象类实现下
using System;
//控制器抽象类
public abstract class Controller
{
//获取模型
protected T GetModel<T>()
where T:Model
{
return MVC.GetModel<T>() as T;
}
//获取视图
protected T GetView<T>()
where T : View
{
return MVC.GetView<T>() as T;
}
//注册模型
protected void RegisterModel(Model model)
{
MVC.RegisterModel(model);
}
//注册视图
protected void RegisterView(View view)
{
MVC.RegisterView(view);
}
//清理注册的视图
protected void ClearView()
{
MVC.ClearView();
}
//注册控制器
protected void RegisterController(string eventName,Type controllerType)
{
MVC.RegisterController(eventName, controllerType);
}
//处理系统消息
public abstract void Execute(object data);
}
//模型抽象类
public abstract class Model
{
public abstract string Name { get; }
protected void SendEvent(string eventName, object data = null)
{
MVC.SendEvent(eventName, data);
}
}
//视图抽象类
using System.Collections.Generic;
using UnityEngine;
public abstract class View : MonoBehaviour
{
//视图标识
public abstract string Name { get; }
//关心的事件列表
protected List<string> AttentionEvents = new List<string>();
//注册关心的事件
public abstract void RegisterEvents();
//事件处理函数
public abstract void HandleEvent(string eventName, object data);
//获取模型
protected T GetModel<T>()
where T : Model
{
return MVC.GetModel<T>() as T;
}
//发送消息
protected void SendEvent(string eventName,object data=null)
{
MVC.SendEvent(eventName, data);
}
}
来到我的游戏,发现其实我用控制器还是少的,(其实是为了加快速度,因为真的很急啊啊啊),优雅的东西总要多做那么一点事嘛(每一个控制器都要注册),如果写出来自己看,所以管他呢,几十个类的引用,真香!开完玩笑,还是老实的来吧,后面我也确实付出偷懒的代价,调试到崩溃。
结语,框架是死的,人是活的,在unity里实际开发的时候这也遇到了这个的很多问题,后面修修改改才勉强完善。还是要灵活运用啊。