中小型项目简单框架ViewSingleton

最近在做一些简单的小型项目,学习了MVC框架:https://blog.csdn.net/ff_0528/article/details/82699360
但是实际使用时发现并不是特别顺手,因为实际项目与数据层几乎没有交互,M和C基本沦为摆饰,虽然能实现解耦但是增加了开发时间成本,实际的维护成本也没有降低,就将上述MVC框架精简了一下,删掉了M和C优化了一些细节,生成了ViewSingleton精简框架。

该框架实现了基于事件触发的系统,但是不完全解耦,项目小的时候通过单例进行适当的耦合度方便快速开发,然后将程序主流程进行事件分配,可维护性高。尤其是针对那种流程性的小项目,比如第一步要做xxx,第二步做xxx,通过事件控制每一步,然后有跨脚本调用需求的,直接单例过去就完事了~

首先编写一个View,继承mono,实现基础的注册单例、注册关心事件、发送消息、接收消息处理:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class View : MonoBehaviour
{
   //注册本身
   public void RegisterSelf()
   {
       EventController.RegisterView(this);
   }

   // 视图层关心的事件列表
   [HideInInspector]
   public List<Consts> attentionEvents = new List<Consts>();

   // 注册视图关心的事件
   public virtual void RegisterViewEvents()
   {

   }

   //发送消息
   protected void SendEvent(Consts eventName, object data = null)
   {
       EventController.SendEvent(eventName, data);
   }

   // 视图层事件处理
   public abstract void HandleEvent(Consts eventName, object data);

}

然后实现一个基于View的单例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class ViewSingleton<T> : View where T : View
{
    private static T instance = null;

    public static T Instance
    {
        get
        {
            if (null == instance)
            {
                instance = FindObjectOfType(typeof(T)) as T;
                if (instance == null) instance = new GameObject("Single of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
            }
            return instance;
        }
    }
    
    protected virtual void Awake()
    {
        if (instance == null) instance = this as T;
    }
}

再编写事件控制系统EventController,用于注册View和发送事件:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class EventController
{
    private static Dictionary<string, View> views = new Dictionary<string, View>();  //名字---视图

    //注册视图
    public static void RegisterView(View view)
    {
        string name = view.GetType().ToString();
        if (views.ContainsKey(name)) return;
        views[name] = view;
        view.RegisterViewEvents();  //注册关心的事件
    }

    //发送事件
    public static void SendEvent(Consts eventName, object data = null)
    {
        //视图层
        foreach (View v in views.Values)
        {
            if (v.attentionEvents.Contains(eventName))
                v.HandleEvent(eventName, data);
        }
    }
}

最终使用的时候就很简单了

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UITest : ViewSingleton<UITest>
{
    new void Awake()
    {
        //在每个物体Awake的时候自己注册,也可以用FindObjectOfType在其他脚本搜到后注册
        RegisterSelf();

    }

    private void Start()
    {
        //发送事件
        SendEvent(Consts.E_StartUp);
    }

    public void Test()
    {
        Debug.Log("test");
    }


    public override void RegisterViewEvents()
    {
        //添加关心的事件
        attentionEvents.Add(Consts.E_StartUp);
    }

    public override void HandleEvent(Consts eventName, object data)
    {
        switch (eventName)
        {
            case Consts.E_StartUp:
                {
                    //若事件触发,调用相关函数
                    Debug.Log("E_StartUp");
                    Test();
                }
                break;
        }
    }

}

还需要一个小小的枚举来记录事件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Consts
{
    //用枚举记录所有事件
    E_StartUp,
    E_OpenUI

}

如果不想要单例也很简单,直接继承View即可,如果不想要继承View的单例,就重写一个单例即可,附赠单例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance = null;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType(typeof(T)) as T;
                if (instance == null) instance = new GameObject("Chinar Single of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
            }

            return instance;
        }
    }

    private void Awake()
    {
        if (instance == null) instance = this as T;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值