最近,因为公司的项目一直在研究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. Caffe+CUDA7.5+CuDNNv3+OpenCV3.0+Ubuntu14.04 配置参考文献 以及 常见编译问题总结

    Caffe+CUDA7.5+CuDNNv3+OpenCV3.0+Ubuntu14.04  配置参考文献 ---- Wang Xiao Warning: Please make sure the cud ...

  2. PowerBuilder 简介及应用 - 数据库系统原理

    PowerBuilder 是一种企业级数据库前端应用和多层体系结构开发工具,友好的用户界面,功能强大的数据窗口,是一个集成开发环境. PB 的特点 采用面向对象的编程方法和事件驱动的工作原理. 支持跨 ...

  3. Chrome Devtools简介

    Chrome开发工具(又称DevTools),是一套内嵌在chrome浏览器内部的web编写和调试工具.DevTools提供给web开发人员深入地访问浏览器内部和web应用的机会.DevTools可以 ...

  4. 在CentOS上安装并运行SparkR

    环境配置—— 操作系统:CentOS 6.5 JDK版本:1.7.0_67 Hadoop集群版本:CDH 5.3.0 安装过程—— 1.安装R yum install -y R 2.安装curl-de ...

  5. union和union all的区别

    UNION 写一篇联合查询(把前后两个表的查询结果集合在前表中)首先有个为什么需要 相同记录数?? 记错了.应该是union两张表的查询字段数目要一致,字段类型要相似相同的数据类型,至少是相似,可转化 ...

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

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

  7. C语言函数指针实验

    上次看Atmel的示例工程,发现人家使用了函数指针的结构体(函数指针结构体).感叹人家的C语言功夫审核,自己费劲还是只能读懂的份.不过,函数指针确实好用.今天就试试这个超牛的东西.Now let's ...

  8. android 学习第一天 了解事件机制,页面跳转等常用操作

    点击时间2种 第一种,通过初始化页面 写入点击事件 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedI ...

  9. 序列化Image到byte[]

    using System.Runtime.Serialization.Formatters.Binary; //引入供序列化Image对象使用 /// <summary>/// 将byte ...

  10. Js中JSON数据交换使用总结

    Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...