最近,因为公司的项目一直在研究StrangeIoc框架,小有所得,略作记录。

StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对unity开发的一款框架,非常好用。

一、先说下MVCS分别代表什么

  1、框架其实就是一种模块的分离,一种写代码的规则,所为的目的都是便于代码的管理修改,更有利于编码思维。

    做游戏很重要的一点就是将UI和逻辑剥离出来,StrangeIoc框架就很好地实现了UI和逻辑的分离以及各个模块的分离。下面我将自己的感想一一道来。

    1、M  即Model 是本地数据类型 比如从服务器、表、xml等获得的数据赋值给model,以后再取用数据时直接读取model对象即可。一般为单例的对象。

    2、V  即View  是视图    一般就是UI这一块,在StrangeIoc中View一般以组件的形式挂在物体身上的,负责查找UI上需要交互的对象。并且在view中提供更新UI的方法。

    3、C  即Command  是命令   在Strangeioc中会和事件绑定,绑定后只要触发事件就会执行对应的Command,Command是框架的核心 负责和service、model 以及 Mediator(中间层)的交互。

    4、S  即Service   是服务层  属于服务端数据,请求数据,更新数据,保存数据等。  

  2、大致清楚了各个层之间的关系和每层的功能以及互相交互的对象就很清晰了,下面这张图是对上文的补充,是StrangeIoc官方提供的结构图,类似UML类图。这张图真的很好,需要仔细研究。

    我以自己的demo为例进行逐步解析。

    1、Root  是整个框架的起点,是挂在物体上的,继承自ContextView 间接继承自MonoBehavior 他的主要功能是创建Context

      

  /// <summary>
/// 框架启动点 挂在场景物体上
/// </summary>
public class Demo01ContextView : ContextView {
void Awake()
{
this.context = new Demo01Context(this); //开启框架
}
}

    2、Context 这个类是整个框架中耦合的地方,继承自MVCSContext ,主要功能负责进行绑定(mapBinding)。

 using UnityEngine;
using strange.extensions.context.impl;
using strange.extensions.context.api; /// <summary>
/// 上下文 做绑定 包括MVCS和一个StartCommand命令绑定
/// </summary>
public class Demo01Context : MVCSContext {
public Demo01Context(MonoBehaviour view) : base(view) { } protected override void mapBindings()
{
//model
injectionBinder.Bind<ScoreModel>().To<ScoreModel>().ToSingleton(); //模型数据绑定为单例模式 //serivce
injectionBinder.Bind<IScoreSerivces>().To<ScoreSerivces>().ToSingleton(); //绑定接口具体实现的类 也是单例模式 //command
commandBinder.Bind(Demo01CommandEvent.RequestScore).To<RequestScoreCommand>(); //绑定事件命令 这个命令是自定义的 这里是请求分数
commandBinder.Bind(Demo01CommandEvent.UpdateScore).To<UpdateScoreCpmmand>(); //当dispatchar这个命令时 UpdateScoreCommand里的execute方法就会执行
//mediator
mediationBinder.Bind<CubeView>().To<CubeMediator>(); //视图和中间层绑定 //绑定一个StartCommand事件 这个事件 是框架里定义的 是开始命令
commandBinder.Bind(ContextEvent.START).To<StartCommand>().Once(); //绑定事件命令用括号 是字段不是类型 //To<StartCommand>(); // Bind<ContextEvent.START>.To<StartCommand>();
}
}

    3、Mediator  类 负责和UI交互,和Command交互

 /// <summary>
/// cubeView的中间层 和view,command交互
/// </summary>
public class CubeMediator : EventMediator
{
[Inject]
public CubeView cubeView { get; set; } //注入cubeView //[Inject(ContextKeys.CONTEXT_DISPATCHER)]
//public IEventDispatcher dispatcher { get; set; } //[Inject]
//public ScoreModel scoreModel { get; set; } //view创建 mediator就会创建 这个方法就会执行
public override void OnRegister()
{
cubeView.Init(); dispatcher.AddListener(Demo01MediatorEvent.ScoreChange, OnScoreChange); //给事件添加监听 以及回调函数 全局的 cubeView.dispatcher.AddListener(Demo01MediatorEvent.ClickDown, UpdateScore); dispatcher.Dispatch(Demo01CommandEvent.RequestScore); //请求分数的命令 }
//view销毁 mediator就会销毁 这个方法就会执行
public override void OnRemove()
{
Debug.Log("OnRemove"); dispatcher.RemoveListener(Demo01MediatorEvent.ScoreChange,OnScoreChange); cubeView.dispatcher.RemoveListener(Demo01MediatorEvent.ClickDown, UpdateScore);
}

    4、 Command类   命令

 /// <summary>
/// 请求分数的命令
/// </summary>
public class RequestScoreCommand : EventCommand { [Inject]
public IScoreSerivces scoreSerivces { get; set; } [Inject]
public ScoreModel scoreModel { get; set; } public override void Execute()
{
Retain(); //因为请求分数会有延迟,这个可以保证这个命令不会被销毁 scoreSerivces.dispatcher.AddListener(Demo01SerivcesEvent.RequestScore, OnComplete); scoreSerivces.ResquestScore("http://xxx/xxx/xxx");
} private void OnComplete(IEvent evt)
{
Debug.Log("request score complete " + evt.data); scoreModel.Score = (int)evt.data; //赋值 dispatcher.Dispatch(Demo01MediatorEvent.ScoreChange, evt.data); scoreSerivces.dispatcher.RemoveListener(Demo01SerivcesEvent.RequestScore,OnComplete); Release(); //释放命令
}
}

    5、View 类  视图类

 /// <summary>
/// 视图会挂在对应的物体上 只会和对应的mediator交互
/// </summary>
public class CubeView : View
{
[Inject]
public IEventDispatcher dispatcher { get; set; } //局部的dispatchar 在对应的mediator中绑定回调方法 public Text scoreText; /// <summary>
/// 初始化方法
/// </summary>
public void Init()
{
scoreText = GetComponentInChildren<Text>();
}
/// <summary>
/// 自身移动
/// </summary>
void Update()
{
this.transform.Translate(new Vector3(Random.Range(-, ), Random.Range(-, ), Random.Range(-, )) * 0.2f);
} /// <summary>
/// 检测点击 加分
/// </summary>
void OnMouseDown()
{
Debug.Log("OnMouseDown");
dispatcher.Dispatch(Demo01MediatorEvent.ClickDown); //触发事件
}
/// <summary>
/// 更新分数方法
/// </summary>
/// <param name="score">新的分数</param>
public void UpdateScore(int score)
{
scoreText.text = score.ToString();
}
}

    6、Service类

 /// <summary>
/// 服务端接口 定义了一些方法
/// </summary>
public interface IScoreSerivces
{
void ResquestScore(string url); //请求分数
void OnReceiveScore(); //收到分数
void UpdateScore(string url, int score); //更新分数 IEventDispatcher dispatcher { get; set; }
}
 /// <summary>
/// IScoreSerivces的一种实现
/// </summary>
public class ScoreSerivces : IScoreSerivces
{
//请求分数
public void ResquestScore(string url)
{
Debug.Log("Resquest score serivces : " + url);
OnReceiveScore(); } public void OnReceiveScore()
{
int score = Random.Range(, );
dispatcher.Dispatch(Demo01SerivcesEvent.RequestScore,score);
} public void UpdateScore(string url, int score)
{
Debug.Log("Update the score : " + url + " new score : " + score);
} [Inject]
public IEventDispatcher dispatcher { get; set; }
 

   7、Model  保存本地数据

 public class ScoreModel  {
public int Score { get; set; } //分数
}

    8、自定义的事件(枚举类型)  用于dispatchar派发事件

 public enum Demo01CommandEvent
{
RequestScore,
UpdateScore
}

二、代码执行顺序

    第一次看框架都会被框架的代码执行顺序弄的很乱,我也是,刚开始根本摸不到头脑,迷迷糊糊只知道这样写就能实现。

    1、首先ContextView 会创建一个context,context会进行bind,之后当前面的类进行创建时,bind的类会按照你制定的规则自动创建,

    2、之后程序会找到框架内的一个Start命令进行执行ContextEvent.START,他会执行绑定的Command里的Execute方法,

    3、这在同时当View类被创建时Mediator类也会创建,并且执行OnRegister方法。

    这三块的方法执行顺序弄清楚之后就有些眉目了。就可以在不同的方法里写自己的实现了。

三、 其他重要的东西

    1、Bind StrangeIoc提供了一个很重要的功能,就是绑定的功能,在context中做绑定,可以绑定类和类,接口和类,类和方法,事件和命令等等 都可以进行绑定,并且可以指定绑定后的规则

          如单例,执行一次后销毁,指定name等。

    2、Inject   说了Bind不得不说,StrangeIoc是依赖注入的框架,Inject就是注入,他的功能就是我们想获得某种类型的对象时不需要自己去创建,只要加上[Inject]标识就可以根据你bind时的规则获得对象。

    3、Mediator  中间层,负责和UI交互 和Command之间交互。他的功能就是隔离了UI和逻辑。UI只能和Mediator交互。

    4、dispatcher  派发器,是StrangeIOC实现的消息发送机制,分为全局dispatcher和局部dispatcher,全局的dispatchar在任何地方都可以发送消息,发送消息后会触发该消息的回调做出响应

            局部的dispatchar通过对象进行发送消息。需要在Mediator中进行注册消息,并制定消息的回调。

四、 结束

    暂时先写这么多,高深的我也没有研究到,目前对框架的感觉是,框架做到了各个模块的分离,使我在写代码的时候对功能划分更加清晰,并且在后期修改功能添加功能时,很方便,这就是框架的魅力吧。

  随着对框架的理解我会继续更新,大家一起努力。

树欲静而风不止,子欲养而亲不待。

2016年12月1日17:11:42

更新  (时间 2016年12月15日11:01:25)

  随着项目的进展,对框架也更加深入的了解。

  增加几点小的知识点

    1、dispatchar 消息发送机制 分为全局消息和局部消息

      a.局部消息: 指view层好对应的mediator层进行的通信,在view层声明一个事件的名称 (public const string On_MyBtn_Click = “On_MyBtn_Click ”)可以在mediator层为这个事件注册方法

      

  protected void UpdateListeners(bool enable)
{
view.dispatcher.UpdateListener(enable, GouJianBarView.On_MyBtn_Click, OnMyBtnClick);
}

        是不是很简单,这样就能实现消息的注册,调用的时候更简单  在需要的地方 当然是在对应的view层中才能调用 dispatcher.Dispatch(On_MyBtn_Click);

      b.全局消息:指的是可以在mediator层互相通信,需要一个发送事件命令的ENUM类型里管理这些命令,在具体功能实现的地方给这个消息注册方法,

   protected void UpdateListeners(bool enable)
{
dispatcher.UpdateListener(enable, UIEventSend.Send_GouJian_JiangJie_Refresh_UIStyle, RefreshUIData);
}

        是不是也很简单,其实原理都是一样的,只是他的范围更广,可以在其他的也只能在mediator层发送这个消息,执行这个回调方法。

      另外还有一种,当项目比较大的时候可以采用这种通信,就是一个消息对应一个Command,并且需要把这个消息在Context中进行bind  就像绑定开始命令一样。这样就可以把实现写在Command中。

    2.view层Awake和Start方法

      在重写view层的Start方法时,需要注意,一定要先执行他父类的方法base.Start();如果不先执行,就没办法自动创建改view层对应的meidator,自动创建是在框架中执行的。

      如果你在view层进行注入数据,一般不推荐在view层直接注入官方推荐的在Mediator层进行注入,view去和mediator层交互。在view中注入数据在Awake方法中是调用不到的 会报空引用 因为,数据的

      注入执行顺序在Awake之后,在Start之前。从而可以看出,mediator层的OnRegister方法是晚于Awake执行,早于Start方法的。

    今天就更新到这,有了新的发现再次更新,或开新的随笔,欢迎交流指正。

     

树欲静而风不止,子欲养而亲不待。

框架上 有其他问题 加群学习165628892(进群备注:博客)  随时提出问题解决问题!

StrangeIoc框架学习----在项目中实战的更多相关文章

  1. 在进行vue的学习,项目中需要引入bootstrap、jquery的步骤。

    在进行vue的学习,项目中需要引入bootstrap.jquery的步骤. 一.引入jQuery 在当前项目的目录下(就是package.json),运行命令 cnpm install jquery ...

  2. WebCollector2.7爬虫框架——在Eclipse项目中配置

    WebCollector2.7爬虫框架——在Eclipse项目中配置 在Eclipse项目中使用WebCollector爬虫非常简单,不需要任何其他的配置,只需要导入相关的jar包即可. Netbea ...

  3. okHttp,greenDao,EventBus组合框架项目中实战

    okHttp,greenDao,EventBus组合封装 zzyandroid 介绍 开门见山,大体思路是在Activity中启动服务,通过服务创建Http请求,请求处理结果通过EventBus通知前 ...

  4. Python框架学习之Flask中的常用扩展包

    Flask框架是一个扩展性非常强的框架,所以导致它有非常多的扩展包.这些扩展包的功能都很强大.本节主要汇总一些常用的扩展包. 一. Flask-Script pip install flask-scr ...

  5. Python框架学习之Flask中的蓝图与单元测试

    因为Flask框架的集成度很低,随着Flask项目文件的增多,会导致不太好管理.但如果对一个项目进行模块化管理的,那样子管理起来就会特别方便.而在Flask中刚好就提供了这么一个特别好用的工具蓝图(B ...

  6. StrangeIoc框架学习

    StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对Unity3D开发的一款框架,非常好用. 一.MVCS分别代表什么 MVCS框架是一种模块的分离,一种写代码的规则,目 ...

  7. RabbitMQ之项目中实战

    说了那么多,还不是为了在项目中进行实战吗,在实践中检验真理,不然我学他干嘛,不能解决项目中的实际问题的技术都是耍流氓... 一.后台管理系统发送消息 瞎咧咧:后台管理系统发送消息到交换机中,然后通知其 ...

  8. 04——Solr学习之项目中使用solr

    借鉴博客:https://blog.csdn.net/kisscatforever/article/details/76744768 完全可以跟着他这个来,清晰明了. 一.来说说怎么使用solr这玩意 ...

  9. Python框架学习之Flask中的视图及路由

    在前面一讲中我们学习如何创建一个简单的Flask项目,并做了一些简单的分析.接下来在这一节中就主要来讲讲Flask中最核心的内容之一:Werkzeug工具箱.Werkzeug是一个遵循WSGI协议的P ...

随机推荐

  1. phpstorm 配置 babel 支持EcmaScript6

    1.安装nodejs 2.npm install --save-dev babel-cli 3.npm install babel-preset-es2015 --save-dev 4.phpstor ...

  2. Python之路,day8-Python基础

    ***面向对象的好处*** 更容易扩展.提高代码使用效率,使你的代码组织性更强,更清晰 更适合复杂项目的开发 封装 把功能的实现细节封装起来,只暴露调用接口 继承 多态 接口继承 定义 类----&g ...

  3. openacs与easycwmp的对接

    原创作品,转载请注明出处 copyright:weishusheng   2015.3.18 email:642613208@qq.com 平台: Linux version 2.6.32-279.e ...

  4. jQuery实例——jQuery实现联动下拉列表查询框--转http://www.cnblogs.com/picaso/archive/2012/04/08/2437442.html#undefined

    jQuery实例--jQuery实现联动下拉列表查询框   在查询与列表显示的时候经常用到联动列表显示,比如一级选项是国家,二级选项是省,三级是市,这样的联动是联系的实时导出的,比如你不可能选择了四川 ...

  5. DE2-115开发板学习(1_时钟信号引脚分配与复位信号的产生)

    1.DE2-115开发板资源 Altera EPCS64 Configuration Device 64MB SDRAM (两片) 50MHz Oscillator EP4CE115F29C7(4PL ...

  6. mac java 安装路径

    google了一下,发现了这篇文章Important Java Directories on Mac OS X,可以使用工具命令"/usr/libexec/java_home"来定 ...

  7. AMD高级应用(翻译)

    Dojo now supports modules written in the Asynchronous Module Definition (AMD) format, which makes co ...

  8. Windows2003 IIS6.0支持32位和64位两种模式的设置方法

    IIS 6.0 可支持 32 位和 64 位两种模式.但是,IIS 6.0 不支持在 64 位版本的 Windows 上同时运行这两种模式.ASP.NET 1.1 只在 32 位模式下运行.而 ASP ...

  9. xampp出现 Access forbidden! 问题解决

    解决 XAMPP 出现 A今天安装了XAMPP 试了下,增加虚拟主机时出现没权限,apache配置文件httpd.conf的allow属性,把下图中的文字注释掉: 然后公开于外网出现以下错误,也很容易 ...

  10. webstorm(注册,激活,破解,码,一起支持正版,最新可用)(2016.9.2更新)

    webstorm(注册,激活,破解,码,一起支持正版,最新可用)(2016.9.2更新)   来源于:http://blog.csdn.net/xx1710/article/details/51725 ...