收藏 分销(赏)

html5引擎开发 -- 引擎消息中心和有限状态机 - 初步整理.doc

上传人:s4****5z 文档编号:8951778 上传时间:2025-03-09 格式:DOC 页数:8 大小:119.50KB 下载积分:10 金币
下载 相关 举报
html5引擎开发 -- 引擎消息中心和有限状态机 - 初步整理.doc_第1页
第1页 / 共8页
html5引擎开发 -- 引擎消息中心和有限状态机 - 初步整理.doc_第2页
第2页 / 共8页


点击查看更多>>
资源描述
一 什么是有限状态机        FSM (finite-state machine),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。他对于逻辑以及时序的控制能起到非常重要的作用。 代码主要看的是什么?逻辑!所有的设计模式无非是让程序逻辑变得更加利与维护,利于优化,利于升级而已。 那么能不能把业务逻辑整理出来统一操作呢? 你可以理解状态机就是干这个的(当然不仅仅是这样)。这样一来只要将一个业务看成一个状态机,有N中状态,然后统一来控制这些状态时的操作。 大家都用过dom事件绑定,是不是某种状态时候就会触发某种事件?这明显也是状态机的概念能解释的。还有观察者模式或者说是订阅发布模式,抑或是jquery的deffered和pomise,甚至是各种同步编程模块(windjs)等等等等。仔细想想也基本上都是同样的原理:即根据不同的消息,诱发注册的相应回调。区别仅仅是怎么注册或者说生成支持各自机制的对象而已。 将各种业务状态写在一起集中管理的好处是什么?就是你整个流程会变得无比的清晰,一目了然!而不再需要将业务逻辑写的到处都是。方便了整体业务逻辑的管理。(后期会抽象出消息机制概念,彻底解放模块之间的耦合,敬请期待) 二 状态机的一些概念          1 状态转换 从一个状态切换到另外一个状态被称为状态转换          2 触发事件 状态改变而引起它的事件称为触发事件.,而触发时间完全可以集中在一起定义,方便管理.业务流程一目了然。   三 会用在哪些场景          状态机可以用在任何能抽象出业务流程的地方,大到页面加载,引擎加载,购物流程,小到tab标签,显示隐藏控件,等等地方。          会不会经常被一大堆的回调函数,异步函数回调之间的逻辑高的头昏眼花?抽象出一个状态机来,外部的各种操作(异步,同步,回调)只需要改变这个状态机的状态就可以执行相应的操作了。 四 举个例子          试想一下,比如我们加载引擎的业务流程:                   --初始化引擎(initcore)                   --初始化模板(inittpl)                   --获取数据(initdata)                   --初始化页面(initpage)                   --初始化页面成功(pageok)          我们可以将这个业务流程生成一个状态机,比如叫“app”,那么我们需要做的是什么呢? 我们只需要将这些状态赋予这个叫做“app”的状态机对象,同时生成一个状态改变时的触发事件管理器。就可以方便并集中地来管理整个业务流程了。逻辑代码展现大概如下: var fsm = FSM.create([’initcore’,’inittpl’,’initdata’,’initpage’,’pageok’],         function(from,to,data){           switch(to){             case ‘initcore‘:             break;             case ‘coreok’:             break;                          case ‘pageok’:             break;         }       });   这样一来整个app加载流程就会一目了然,而不管是在异步中还是页面回调中需要业务变更时,只需要改变对应状态机的状态就会执行相应的逻辑。比如:          fsm.change(‘pageok’); 我们可以称之为面向业务的状态模型,也可以称之为状态模式。   下面,我们再来看看消息中心的想法。   五 关于状态机为核心的消息中心抽离          5.1让我们看看以前的模块式开发          以前引擎和模块,模块和模块之间,一般都是互相直接调用接口,也就是api模式。这就是面向对象基本模式了,每一个模块都是一个对象,对外开放了很多接口,其他对象只需要调用目标对象的相应接口就可以执行相应的逻辑。目前来说,基本上都是这样的设计模式,这种方式为我们带来了很大的便利(图)。       5.2提出问题 但是这样没法避免的一个问题就是,在一个模块内部需要直接调用另外一个模块的api,你中有我,我中有你。试想一下,如果另外一个模块不存在,接口不存在呢,或者接口返回错误的情况下该怎么办呢?不至于每个调用其它模块的地方全部都写上容错吧,那么代码基本没法看了。 那么我们就该想想了,是不是应该有这样一套机制呢,暂时叫做调度中心,我们简单设想一下它应该有一下功能: 1 调度中心能统一的管理引擎以及各个模块之间的相互调用,以方便记录当前应用运行的的各种实时操作。 2 所有的模块不会直接调用其他模块的接口,而是告诉调度中心,我要调哪个模块的哪个方法, 并提供必要的参数,调度中心会解析消息并调用相应的模块,当然必要的错误处理机制是必须的。 3 每个模块必须有相应的消息处理机制,有调度中心统一方法“吃入”模块,当然必要的配置文件是必须的。 这就是我们说的消息机制。O(∩_∩)O~   5.3什么是消息机制         每个引擎都会有很多很多的模块,好的引擎模块间的耦合会比较松,但是大多数引擎模块之间都是结合的很紧密的。     消息,很多情况下都跟通信相关。那么消息机制应用到引擎中是什么样子呢?(图)     5.4要注意的问题     1    流程上增加了复杂度,开发一个高效的消息中心很重要 2    每个模块需要注册进消息中心 3    消息错误时 要有统一处理机制     总结:        想一下,状态机作为消息中心的核心引擎来实现消息中心思想,是不是很给力呢? C# 白话系列之——白话委托 今天看到首页有个委托的文章,但大都写的太专业,而且没有实用的例子场景。正好昨天做了一个有关委托的功能,所以也来凑个热闹,用白话掰掰 一、委托是什么 我们都知道数据类型,简单点的如,想给一个变量赋值整数,那就要定义一个 int类型的变量 int var=5;   想给一个变量赋值字符串那就定义一个string类型的变量 string var ="test";   复杂点的就是自己定义一个类,然后就可以定义类变量  MyClass myClass= new MyClass();   现在我们有如下一个方法,怎样把这个方法可以赋值给一个变量呢? public string GetMessage(string messageType) { string ret = ""; switch (messageType) { case "error": ret = "错误消息"; break; case "warning": ret = "警告消息"; break; default: ret = "未知消息"; break; } return ret; }   这个就要委托来登场了。先看实现 delegate string MessageDelegate(string messageType); public void Test() { MessageDelegate myMessage = GetMessage; string ret = myMessage("error"); } 定义一个类大家都会 ,用 class 关键字来定义一个类MyClass class MyClass { } 同理,用 delegate 关键字来定义一个委托 MessageDelegate。 一定要有这个一个概念,我们用 delegate 关键字定义的委托(MessageDelegate)是一个数据类型。 int 类型的变量用来赋值整数的,string类型的变量用来赋值字符串的,而委托类型的变量是用来赋值函数的。   当然因为每个函数的参数不同,返回的数据不同,所以在定义委托的时候也就指明了这个委托类型的变量可接受的函数。 delegate string MessageDelegate(string messageType); 如上面定义的MessageDeletegate委托数据类型,用MessageDeletegate定义的变量(myMessage)只能接受 有一个string类型的参数并且有一个sting返回值的函数(GetMessage) MessageDelegate myMessage = GetMessage;   delegate void MyDelete(int i); 上面定义的这个MyDelete委托类型对应的函数是有一个int类型的参数,并且没有返回值。   二、委托的使用 在.net中委托基本随处可见,最常用的就是Action、Func和Predicate,它们分别有很多重载,自己可以看看。 public delegate void Action(); public delegate TResult Func<out TResult>(); public delegate bool Predicate<in T>(T obj);   现在有这么一个功能: 现在有一个int类型的集合,把所有的偶数乘以2,输出到一个新集合中。 测试数据: List<int> myList = new List<int>(); for (int i = 0; i < 10; i++) { myList.Add(i); } 普通方法实现: List<int> retList = new List<int>(); for (int i = 0; i < myList.Count; i++) { if (myList[i] % 2 == 0) { retList.Add(myList[i] * 2); } } 用委托方法实现: List<int> retList = new List<int>(); myList.ForEach((data) => { if (data % 2 == 0) { retList.Add(data * 2); } }); 当然这个ForEach是.net提供的扩展方法,再加上lambda表达式实现。 这个还不足以说明委托的好处。   如果我们再把问题放宽点,现在有一个int类型的集合,如果里面的数字满足某个条件,则执行某个动作。 public void MyOperation(List<int> myList, Func<int, bool> func, Action<int> action) { for (int i = 0; i < myList.Count; i++) { if (func(myList[i])) { action(myList[i]); } } }   现在在把第一个问题实现下: MyOperation(myList, (d) => { return d % 2 == 0; }, (d) => { retList.Add(d * 2); });   可以近一步写成扩展方法,这个有跑题有点远了。   上面这个例子主要是说明了一点: 委托是一个函数类型的数据类型(对比int是一个整数类型的数据类型),可以把委托当做参数变量来传递。 然而因为委托变量的值是函数,这样就可以把一个函数当做参数传递到另外一个函数中。   如上面提到的: 写一个对集合操作的函数,如果集合里面的某个元素满足某个条件,则执行某个动作。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服