Unity 3D Framework Designing(4)——设计可复用的SubView和SubViewModel(Part 1)
『可复用』这个词相信大家都熟悉,通过『可复用』的组件,可以大大提高软件开发效率。 值得注意的事,当我们设计一个可复用的面向对象组件时,需要保证其独立性,也就是我们熟知的『高内聚,低耦合』原则。
组件化设计的思路
不管是开发客户端应用程序还是开发服务器端应用程序,『组件』这个词我们并不陌生。不管是在iOS中的xib,还是在AngularJS的Component,或者后端开发的 User Control,可复用的组件是面向对象开发的基础。所以在Unity 3D 框架设计时,组件化是核心的概念。那么如何去设计SubView和SubViewModel,我总结出几条原则:
- 当一个功能被不同的场合频繁用到,建议将这个功能抽象成SubView(SubViewModel)
- SubView(SubViewModel)应该保持高内聚,低耦合原则
- SubViewModel不应该处理具体的业务逻辑,它很单纯,可通过委托Delegate的方式交由外部处理
构建SubView和SubViewModel
假设现在有如下一个需求,需要绑定角色的信息到头像上,如下图所示:

这是一个很常见的需求,创建一个MonoBehaviour,定义Public的变量并引用这些控件,最后再将这个MonoBehaviour附加到GameObject上,很快就能完成。当然,我不能说这样的实施是错误的,毕竟我们只要保证运行正确就可以了。
看到左上角的勋章吗,这个勋章会在不同的场景出现,我们优先把它考虑成一个SubView(BadgeView),也就是最外层的FaceBoxView里嵌套了一个BadgeView。
public class FaceBoxView:UnityGuiView<FaceBoxViewModel>
{
public Text nameText;
public Text levelText;
public Image faceImage;
public BadgeView badgeView;
}
我们在分析一下BadgeView需要什么数据?它需要武器的Icon和属性颜色,所以我们抽象出一个Badge的DataModel:
public class Badge
{
public string Icon { get; set; }
public string ElementColor { get; set; }
}
所以对于FaceBoxViewModel而言,它为FaceBoxView服务。FaceBoxView需要什么数据,它就提供什么数据。显然它需要提供Name,Level,Face以及Badge组件的DataModel:
public class FaceBoxViewModel:ViewModelBase
{
public readonly BindableProperty<string> Name=new BindableProperty<string>();
public readonly BindableProperty<int> Level=new BindableProperty<int>();
public readonly BindableProperty<string> Face=new BindableProperty<string>();
public readonly BindableProperty<Badge> Badge=new BindableProperty<Badge>();
public override void OnStartReveal()
{
base.OnStartReveal();
Initialization();
}
public void Initialization()
{
Name.Value = "比尔";
Level.Value = 9;
Face.Value = "Avatar204_Face";
Badge.Value = new Badge() {Icon = "Icon_WeaponRod", ElementColor = "1CB9FFFF"};
}
}
因为Badge是BindableProperty类型对象,特点是当Badge Value改变时,触发的OnValueChanged事件就可以给BadgeViewModel传递数据,从而初始化BadgeView:
protected override void OnInitialize()
{
base.OnInitialize();
Binder.Add<string>("Name",OnNamePropertyVlaueChanged);
Binder.Add<int>("Level",OnLevelPropertyValueChanged);
Binder.Add<string>("Face",OnFacePropertyValueChanged);
Binder.Add<Badge>("Badge",OnBadgePropertyValueChanged);
}
private void OnBadgePropertyValueChanged(Badge oldValue, Badge newValue)
{
badgeView.BindingContext = new BadgeViewModel() ;
badgeView.BindingContext.Initialization(newValue);
}
我们可以看到,组件化的实施从代码量上是变得复杂了,组件的颗粒度越细,那么嵌套的层次就越深,如果某个功能只出现一次,并且不会被复用,那么我不推荐将它变为一个SubView(SubViewModel)
小节
本文为大家介绍怎样将组件化模式思想引入到Unity 3D中,其实Unity 3D本身就是基于组件化开发的。在我的uMVVM框架中,组件化概念更细,就像用户控件一样,随拿随走,它们保持高度独立,这样的好处是不会产生紧耦合。
Unity 3D Framework Designing(4)——设计可复用的SubView和SubViewModel(Part 1)的更多相关文章
- Unity 3D Framework Designing(4)——设计可复用的SubView和SubViewModel(Part 2)
在我们设计和开发应用程序时,经常要用到控件.比如开发一个客户端WinForm应用程序时,微软就为我们提供了若干控件,这些控件为我们提供了可被定制的属性和事件.属性可以更改它的外观,比如背景色,标题等, ...
- Unity 3D Framework Designing(6)——设计动态数据集合ObservableList
什么是 『动态数据集合』 ?简而言之,就是当集合添加.删除项目或者重置时,能提供一种通知机制,告诉UI动态更新界面.有经验的程序员脑海里迸出的第一个词就是 ObservableCollection.没 ...
- Unity 3D Framework Designing(3)——构建View和ViewModel的生命周期
> 对于一个View而言,本质上是一个MonoBehaviour.它本身就具备生命周期这个概念,比如,Awake,Start,Update,OnDestory等.这些是非常好的方法,可以让开发者 ...
- Unity 3D Framework Designing(1)—— MVVM 模式的设计和实施(Part 2)
MVVM回顾 经过上一篇文章的介绍,相信你对 MVVM的设计思想有所了解.MVVM的核心思想就是解耦,View与ViewModel应该感受不到彼此的存在.View只关心怎样渲染,而ViewModel只 ...
- Unity 3D Framework Designing(1)—— MVVM 模式的设计和实施(Part 1)
初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...
- Unity 3D Framework Designing(7)——IoC工厂理念先行
一谈到 『IoC』,有经验的程序员马上会联想到控制反转,将创建对象的责任反转给工厂.IoC是依赖注入 『DI』 的核心,大名鼎鼎的Spring框架就是一个非常卓越的的控制反转.依赖注入框架.遗憾的是, ...
- Unity 3D Framework Designing(9)——构建统一的 Repository
谈到 『Repository』 仓储模式,第一映像就是封装了对数据的访问和持久化.Repository 模式的理念核心是定义了一个规范,即接口『Interface』,在这个规范里面定义了访问以及持久化 ...
- Unity应用架构设计(4)——设计可复用的SubView和SubViewModel(Part 1)
『可复用』这个词相信大家都熟悉,通过『可复用』的组件,可以大大提高软件开发效率. 值得注意的事,当我们设计一个可复用的面向对象组件时,需要保证其独立性,也就是我们熟知的『高内聚,低耦合』原则. 组件化 ...
- Unity 3D Framework Designing(2)——使用中介者模式解耦ViewModel之间通信
当你开发一个客户端应用程序的时候,往往一个单页会包含很多子模块,在不同的平台下,这些子模块又被叫成子View(视图),或者子Component(组件).越是复杂的页面,被切割出来的子模块就越多,子模块 ...
随机推荐
- 依赖lean cloud的注册与登录
前言 实现登录注册的基本功能,没有添加手机验证和邮箱验证的功能,有相应的方法,如果需要,可以自己加上其相应的方法 github的网址: 效果图: 正文 1.导入leancloud相应的第三方,这个等我 ...
- Asp.net mvc 知多少(七)
本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...
- 【前端】:JavaScript
前言: 开始学JavaScript,Dom,jQuery了,知识好杂,本身记忆力就不行的~~这篇博客简单介绍下JavaScript. 下篇博客写关于Dom的. JavaScript是一门编程语言(之前 ...
- [java多线程] - Thread&Runnable运用
负载是一个很大的话题,也是一个非常重要的话题.不管是在大的互联网软件中,还是在一般的小型软件,都对负载有一定的要求,负载过高会导致服务器压力过大:负载过低又比较浪费服务器资源,而且当高请求的时候还可能 ...
- vim高亮设置
vim高亮设置 前提: 查看vim是否完整安装 rpm -qa | grep vim 若完整安装,则会出现如下相关信息 vim-filesystem-7.4.629-5.el6.x86_64 vim- ...
- Redis【第一篇】安装
第一步:准备 1. 操作系统 CentOS-7-x86_64-Everything-1511 2. redis 版本 redis-3.2.8 3. 修改内核参数 有三种方式: 1)编辑/etc/sys ...
- Oracle 生成一张测试表并插入随机数据
--生成随机表 --CREATE table scott.One_Million as ( SELECT ROWNUM AS T_ID, TRUNC(DBMS_RANDOM.VALUE(, )) 年龄 ...
- C#之系统异常处理机制
在系统开发过程中,BUG和异常产生是无处不在的,但是需要我们去做的就是不断去发掘异常.修改异常. 这篇文章主要谈谈我在系统中解决异常的几种方法: 1.控制台程序产生的异常: 在大多数的控制台程序中,运 ...
- Java虚拟机学习 - 垃圾收集器
HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器.如果两个收集器之间存在连线,就说明它们可以搭配使用. Serial(串行GC)收集器 Serial收集 ...
- javascript string对象方法总结
1.anchor() 用于创建html锚,也就是a标签,()中可以带参数,是a标签的name属性值. var string="hello world"; document.writ ...