基于MVCS模式的StrangeIoc框架

本文深入解析了strangeIoc框架,这是专为Unity设计的游戏开发框架。文章详细介绍了框架的结构,包括Root启动部分,Context中的代码耦合,mediator作为UI与逻辑的交互层,以及如何通过命令和事件实现UI与逻辑的解耦。此外,还探讨了服务端与数据模型之间的绑定方式,以及具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

strangeIoc框架是专为Unity写的一套游戏开发框架。

框架的作用是方便项目的管理,随着项目增大,没有框架的话,后期很难管理。

Unity开发注重逻辑和UI的分离,UI只负责UI方面,不牵扯代码逻辑,不至于最终混为一团,不利于后期开发和维护。

strangeIoc框架是基于MVCS模式,在MVC的基础上多出了service一层,是MVC框架的变种。完全使UI和逻辑分离。

先来看一下,总体逻辑图。

1.Root 是整个框架的启动部分,挂载场景物体上
/// <summary>
/// Root
/// 启动整个框架
/// </summary>
public class Demo1ContextView : ContextView {

    private void Awake()
    {
        this.context = new Demo1Context(this);
    }
}

2.整个框架代码耦合部分在Context中,负责绑定一些命令,通过绑定命令,简介执行代码。在代码中 只需发起命令,程序

会根据事先绑定好的方法,进行调用。

public class Demo1Context : MVCSContext {

    public Demo1Context(MonoBehaviour view) : base(view)
    {

    }

    //进行绑定映射
    protected override void mapBindings()
    {
        //model
        injectionBinder.Bind<ScoreModel>().To<ScoreModel>().ToSingleton();
        //command
        commandBinder.Bind(Demo1CommandEvent.REQUESTSCORE).To<RequestScoreCom>();
        commandBinder.Bind(Demo1CommandEvent.UPDATESCORE).To<UpdateScoreCommand>();
        //service
        injectionBinder.Bind<IScoreService>().To<ScoreService>().ToSingleton();//表示对象只会在工程生成一次

        //mediator
        mediationBinder.Bind<CubeView>().To<CubeMediator>(); //完成view 和mediator 绑定


        //创建一个StartCommand  绑定开始事件 只触发一次
        commandBinder.Bind(ContextEvent.START).To<StartCommand>().Once();

    }

}

以上绑定分为三种方式:1.commandBinder.Bind,中间命令的绑定的方式。

2. mediationBinder.Bind,中间层的绑定

3.injectionBinder.Bind,服务端和数据模型之间绑定方式

 

3.mediator 类是UI和逻辑之间的交互中间层。UI和逻辑层只需要通过发起Command命令,就可以达到目的。

相应的制定mediator层的命令用于交互

/// <summary>
/// UI向mediator发起的命令
/// </summary>
public enum Demo1MediatorEvent
{
    SCORECHANGE,
    CLICKDOWN    
}
 

/// <summary>
/// mediator层向服务端请求数据命令
/// </summary>
public enum Demo1CommandEvent
{
    REQUESTSCORE,
    UPDATESCORE

}

//mediator层代码

public class CubeMediator : Mediator {

    //注入
    [Inject]
    public CubeView cubeView { set; get; }

    [Inject(ContextKeys.CONTEXT_DISPATCHER)]  //全局的Dispatcher
    public IEventDispatcher dispatcher { get; set; }


    public override void OnRegister()
    {
        cubeView.Init();
        dispatcher.AddListener(Demo1MediatorEvent.SCORECHANGE,OnScoreChange);
        cubeView.dispatcher.AddListener(Demo1MediatorEvent.CLICKDOWN, ClickDown);
        //通过Dispatcher 发起请求分数的命令
        dispatcher.Dispatch(Demo1CommandEvent.REQUESTSCORE);

    }
    public override void OnRemove()
    {
        Debug.Log("OnRemove");
        dispatcher.RemoveListener(Demo1MediatorEvent.SCORECHANGE, OnScoreChange);
        dispatcher.RemoveListener(Demo1MediatorEvent.CLICKDOWN, ClickDown);
    }

    public void OnScoreChange(IEvent evt)
    {
         cubeView.UpdateScore((int)evt.data);
       
    }

    public void ClickDown()
    {
        dispatcher.Dispatch(Demo1CommandEvent.UPDATESCORE);
    }

}

//UI层

public class CubeView : View {

    [Inject]
    public IEventDispatcher dispatcher { get; set; }

    private Text _scoreText;

    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
        _scoreText = this.GetComponentInChildren<Text>();
    }


    private void Update()
    {
        transform.Translate(new Vector3(Random.Range(-1, 2), 
            Random.Range(-1, 2), Random.Range(-1, 2)) * 0.1f);
    }

    private void OnMouseDown()
    {
        Debug.Log("加分");
        dispatcher.Dispatch(Demo1MediatorEvent.CLICKDOWN);
    }

    public void UpdateScore(int score)
    {
        _scoreText.text = score.ToString();
    } 

}

4.请求分数和更新分数

public class RequestScoreCom : EventCommand {

    [Inject]
    public IScoreService scroService { get; set; }
    [Inject]
    public ScoreModel scoreModel { get; set; }

    public override void Execute()
    {
        Retain();//命令是一次性的,所以要保存

        scroService.dispatcher.AddListener(Demo1ServiceEvent.REQUESTSCORE, OnComplete);

        scroService.RequestScore("http://xxx.xxx.xx");
    }

    private void OnComplete(IEvent evt)
    {
       
        scroService.dispatcher.RemoveListener(Demo1ServiceEvent.REQUESTSCORE, OnComplete);

        //把数据保存到数据模型中去
        scoreModel.Score = (int)evt.data;

        dispatcher.Dispatch(Demo1MediatorEvent.SCORECHANGE, evt.data);

        Release(); //到这里使用完之后  在释放命令
    }
}
 

public class UpdateScoreCommand :EventCommand {
    [Inject]
    public ScoreModel scoreModel { set; get; }

    [Inject]
    public IScoreService scoreService { get; set; }

    public override void Execute()
    {
        scoreModel.Score++;
        scoreService.UpdateScore("http://xxx.xxx.xx", scoreModel.Score);
        dispatcher.Dispatch(Demo1MediatorEvent.SCORECHANGE, scoreModel.Score);
       
    }
}

5.服务端随机一个分数

服务端继承接口IService

public interface IScoreService
{
    //向服务器请求分数
    void RequestScore(string url);

    //收到服务器发送过来的分数
    void OnReceiveScore();

    //向服务器提交最新分数
    void UpdateScore(string url, int score);

    IEventDispatcher dispatcher { get; set; }
}

服务端

public class ScoreService : IScoreService
{

    [Inject]
    public IEventDispatcher dispatcher { get; set; }
   
    public void RequestScore(string url)
    {
      
        OnReceiveScore();
    }

    public void OnReceiveScore()
    {
        int score = Random.Range(0, 100);
        dispatcher.Dispatch(Demo1ServiceEvent.REQUESTSCORE, score);
      
    }
    public void UpdateScore(string url, int score)
    {
        Debug.Log("Update Score :" + score + "to url :" + url);
    }
}

 

前言 unity框架,除了各大公司自己内部使用的,开源并好用的实际并不是很多,我会慢慢挖掘,依次写出自己的一点见解,错误的地方,望各路大神指正。 一、基本概念 控制反转(Inversion of Control,英文缩写为IOC),我的理解就是,原本A类要获取B类的对象,需要你在A类中自己New一个对象,那么是由A来获取并控制B的对象,IOC就是把对象获取的这个过程交给容器和依赖注入来处理,A类并不知道B的对象是哪里来的,对B对象的控制,由自己变成了其他类,官方一点的概念可以百度,这个还是蛮多的。 二、StrangeIOC基础类型 实际要理解一个框架的类型,还是要自己看源码,这里我只说一下几个重要类型的作用,这个看源码的时候有个印象,也方便理解,而且说这部分的帖子也很多,我就不再赘述了。 1.Context 上下文组件定义程序边界,也就是可以把一个程序定义成多上下文,让代码更加模块化 它提供了程序入口,也算是框架中耦合度最高的地方 2.Binder和Binding 这两个类是这个框架最重要的组成部分 Binding存储了对象的绑定关系,而Binder存储了Binding的对象 3.View和Mediator MVCS中的View层,View只用于显示,也就是View只负责管理UI,Mediator负责界面逻辑,事件响应等 4.Model MVCS中的Model层,负责数据部分 5.Command MVCS中的Control层,负责执行逻辑代码 6.Service MVCS中的Service层,负责与第三方交互,这个Service我理解的,并不是一定指代服务器,也可以是其他的软件,什么都可以,它就是我们程序对外的接口 7.Dispatcher 派发器是框架内通信主线的其中一种,用来派发消息,触发命令,从而进一步解耦 8.Signal 信号是框架内另外一种通信主线,它采用强类型,来绑定信号和命令之间的关系,实现消息响应的触发 9.ReflectionBinder 反射部分,通过binding来获取类的信息,存储在ReflectedClass中 10.injector 注入器,通过反射获取的信息,来实例化请求的对象 --------------------- 作者:蓝天小僧 来源:优快云 原文:https://blog.csdn.net/zcaixzy5211314/article/details/80876228 版权声明:本文为博主原创文章,转载请附上博文链接!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值