在做这个游戏之初始,对框架还是没啥概念的, 随着工程的越来越大,我才理解,高复用,耦合,内聚这些极抽象的概念。

MVC框架

个人认为这框架还是非常广泛而经典的,虽然游戏的代码都是我写的,但我仍体会到这个框架对团队协作非常的有利,各个层级各做各的,互不相干,但又受到统一的规范管理,多好。。
正题,先百度一波:
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中
在这里插入图片描述
通俗的理解就是
(view)视图就是来显示给用户的,同时视图被玩家控制,接受玩家的输入,例如:游戏里的UI。
(Model)模型用于保存数据,游戏里的状态会保存在模型里,例如: 地图的数据,生成的物体,关卡等等。
(Controller)控制器作用可认为是一个中间层,可以控制视图,也可以控制模型,也是个比较抽象的概念。
举例:玩家装备枪 ,来说明一个工作循环过程:

Created with Raphaël 2.2.0 开始 视图接收输入: 装备枪 控制器分析请求: 改变模型数据 模型发出通知: 装备枪的数据改变 视图收到通知: 显示视图 结束

实际写代码的时候,不明白为什么要加个控制器作为中间层,视图直接操作模型数据不就可以了吗,看起来是那么回事,那先来看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里实际开发的时候这也遇到了这个的很多问题,后面修修改改才勉强完善。还是要灵活运用啊。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐