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(组件).越是复杂的页面,被切割出来的子模块就越多,子模块 ...
随机推荐
- MVC View显示详解(RenderBody,RenderPage,RenderSection,Partial)
一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合 ...
- asp.net core mvc剖析:启动流程
asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...
- java 双击jar包操作
如何使jar包直接双击运行? 测试:MyMenu.java 类名:MyMenu 写完java代码后,发现物理路径下为: 当我按住Shift键,在此处游记,打开命令行窗口: 执行命令:javac My ...
- JAVA中的数据结构 - 1,红黑树
背景: 在JDK源码中, 有treeMap和JDK8的HashMap都用到了红黑树去存储 红黑树可以看成B树的一种: 二叉树-->搜索二叉树-->平衡搜索二叉树-->B树--> ...
- PHP递归遍历指定文件夹内的文件
今天早上在地铁上看了关于文件和文件夹的一章,正好最近刚搞懂linux的文件系统,觉得对文件属性的访问跟Shell命令很像,所以想晚上来实践一下. 发现php的文件夹函数好像没有提供遍历文件夹下的所有文 ...
- JSP 学习二
在基于昨天对JSP学习的基础上,今天我们来学习JSP的指令和JSP 对中文的处理. 一.JSP指令简介 JSP 指令是为JSP引擎而设计,它并不直接产生任何可见的输出,而只是告诉引擎如何处理JSP页面 ...
- NoSql研究报告
NoSql研究报告 1.概述 随着互联网的不断发展,信息系统的数据变得越来越多,关系型数据库逐渐面临着难以克服的障碍,主要体现在: 对数据库的高并发读写需求 对海量数据的高效率存储和访问需求 对数据库 ...
- HTML第一课
<标签名 属性>内容</标签名> <标签/> 静态网页与动态网页的区别:是否从数据库提取数据相对路径跟绝对路径../代表高一级的 牛逼的空格< ...
- php和js中,utf-8编码转成base64编码
1.php下转化base64编码 php中,文本文件的编码决定了程序变量的编码,比如以下代码在不同编码的php文件中,展示的效果也是不一样的 <?php $word = '严'; echo ba ...
- Asp.Net MVC 之 Autofac 初步使用1
Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个: 优点: 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用 较低的学习曲线,学习它非常的简单, ...