mvc设计模式

说到mvvm设计模式不得不先说说mvc设计模式。mvc其实不是一个模式,而是几个模式结合使用的结果,比如观察者模式,通过数据更新通知UI的方式,降低了耦合度。策略模式解决了view可复用的问题。mvc的m实际上既要负责数据存档,还要负责组织UI数据,比较凌乱,所以产生了mvvm模式。

Learning TypeScript中文版第九章对于MV*是这样解释的
  1. model:是一个用来存储数据的组件。在一些框架中model包含了与网络进行通信的方法,而另一些框架中则有单独的模块负责通信获得数据。我将其定义为ItemModel,我不会在这里进行网络通信,而是放到模块管理器中与网络通信。

  2. collection:用来表示一组model。而对于模块而言,我比较倾向于每个模块有一个管理器,单例,管理着model和collection:因为一个模块可能不止一种model或collection。并且定义为UIModel。

  3. itemview:框架提供给我们最主要的功能就是item view(或叫做view)组件。view负责将存储在model中的数据渲染到屏幕上。我在这里也是定义为ItemView,与ItemModel一一对应。

  4. collection view:与model跟collection的关系相同。collection view 也是item view 的容器。负责管理item view。我在这里定义为UIView。与UIModel对应。

  5. controller:通常负责特定的model和相关的view的生命周期。负责实例化model和view。MVC应用的交互式通过组织controller和它的方法。在需要的时候,controller可以有很多方法。这些方法与用户的行为一一对应。也就是说:controller负责与其他模块交互和处理用户行为。

  6. 事件 分为用户事件和程序事件。不论是什么事件都是通过监听和通知的方式进行沟通的。监听的方式又可以分为局部和全局的。如果一个事件希望所有模块都能接收到,那么就用全局事件。而对于模块内部的事件通知就没必要使用全局事件了,直接使用collection,controller,model,都可以做事件推送,通知给自己对应的view。

  7. 路由和导航:这一能力在单页面的游戏中可以理解为模块管理器的角色。给每个模块定义一个ID。然后通过导航进行跳转管理,模块和模块之间只需要知道彼此的id和需要的参数即可。

  8. 中介器:是一个简单的对象,所有其他模块都需要通过它与其他部分进行通信。实现于发布订阅模式。这种方式可以让模块间不用相互依赖。这种方式典型的就是PureMVC,对于大型的项目可能有必要,但是对于游戏而言过于臃肿,所以不建议使用中介器,你会被定义事件,写commond而烦死。

mvvm设计模式

mvvm就是把mvc里面的m的工作分开处理。model:负责存档数据,viewmodel负责组织UI数据。

  1. controller 用于管理UI触发的逻辑事件,给view传入不同的controller,会有不同的处理方式。

  2. model,负责数据存取和全局通知。其实就是保存的用户数据,供所有模块使用。这里的数据可以存放到本地,也可以存放到远程服务器。也有人会定义成ov,其实是一个东西。3.viewmodel: 负责组织存档数据和配置数据供view使用。负责接收model的更新事件更新UI数据同时做模块内通知。给view传入不同的viewmodel会显示不同的数据。

  3. view: 负责解析UI配置文件,绑定点击事件函数,调用controller处理逻辑,调用viewmodel获取数据,接收viewmodel的事件更新UI。5.模块管理器:我之前一直提到的模块管理器其实也是viewmodel,我通常把一个模块最底层的view对应的UIModel定义为模块管理器,单例使用。6.配置数据:它是由数据表生成的,供viewmodel和model使用。

类图

游戏开发中用到的MVVM设计模式_生命周期

对于有后台的游戏,controller调用模型管理器处理数据,模型管理器调用RemoteProxy获取远程的数据,设置Model;对于单机游戏,controller直接调用模型管理器这一步不变,只是模型管理器直接设置Model即可。不过这里要注意数据传递的方向性。总是从model——>viewmodel——>view。

设计模式探讨

为什么每个模块要有一个单例的模块管理器?

1.根据设计模式的最少知识原则,保证模块的独立性,最好是每个模块自己拉取对应的存档数据和配置数据组织自己的view需要的数据。但是开发中往往是一个人负责一个相关的模块,使用其他人开发的模块大多时间不会自己组织数据,那样很费时间,所以使用了单例形式。

2.再有,如果每次弹出UI会创建一个新的模管理器实例,模块管理器就需要与view绑定,当view销毁时移除模管理器注册的全局事件。每次进入UI需要重新组织数据,消耗一定的时间。这里有一个绑定的问题,就是模块管理器的生命周期与view相同的话,好处是不需要管理切换账号的事件监听问题。如果做成单例,注册的全局事件可以不随着view销毁而移除,也不与view绑定,但是在更换账号时需要移除注册的全局事件。

每个模块的controller为什么要单例?

如果模型管理器使用单例,那么controller最好也使用单例。因为controller是负责用户行为的,也就是实现了很多功能,而这些功能是不确定会在哪个地方,会被哪个模块使用的。其实PureMVC在进入游戏后做了很多初始化工作,有一件事就是创建controller实例并注册,其实相当于单例使用了。

模块化管理

游戏开发中用到的MVVM设计模式_mvc_02

模块化管理
  1. 如果有这个Route,我们就需要定义模块ID,将controller注册到Route中。此时,controller不必定义为单例,但是Route中的实例不会消失,相当于单例。一个模块想要调起另一个模块,就通过Route调用就可以。这里的Route肯定是单例的。至于controller是通过事件调用Route还是直接获得Route的实例调用Route就看个人喜好了。我比较喜欢简单直接,没必要整那么多事件名称,浪费时间。

  2. 如果没有这个Route就更简单了。一个模块的controller直接调用另一个模块的controller即可,方便快捷。