在咱们设计和开发应用程序时,常常要用到控件。好比开发一个客户端WinForm应用程序时,微软就为咱们提供了若干控件,这些控件为咱们提供了可被定制的属性和事件。属性能够更改它的外观,好比背景色,标题等,而事件能够丰富控件的行为,好比最多见的『按钮点击』,谁也不能肯定点击以后将发生什么事,是链接数据库呢仍是弹出警告框,在不一样的场景下,『按钮点击』 的行为每每呈现不一致。因此,与其犹豫不定,还不如把处理委托给开发者,这就是『OnClick』事件。git
在上篇文章中,我阐述了为何要使用SubView,总结起来就3个字:『可复用』 。那么问题来了,既然是可复用,那就意味着SubView能够在任何场景下使用,那怎样才能确保它作的是正确的行为呢?github
举个栗子,仍是 以以下图FaceBox为例,不一样的场景下点击头像应该处理不一样的事:数据库
你看,一样一个SubView,在不一样的场景下它的行为每每是不一致的。那咱们怎么去跟踪这些行为呢?设计模式
你可能会以以下方式去定制SubView的行为:ide
void OnClick(){
if(战团){
显示该成员的具体信息
}else if(队伍){
进入换人界面
}else if(战斗){
显示它配置的战术
}else{
//其余
}
}复制代码
仍是那句话这样,这样并无错,甚至对某些SubView而言逻辑还很清晰。但仔细想一想,这是最好的实践吗?spa
因此显然上述代码不是最佳实践。那咱们应该怎样去解决呢?设计
实际从开头的引言我已经提出了解决方案,以事件的形式委托给开发者来肯定。一个Button也好,仍是一个SubView也好,他们都是可复用的组件,不该该与具体的业务逻辑相结合。经过事件或者委托的形式,暴露给开发者来决定究竟要处理什么逻辑,这样才能和具体业务逻辑解耦。代理
仍是以FaceBox举例,那么从上面的分析得出结论,咱们须要定义委托或者事件,那应该定义在FaceBoxView呢仍是FaceBoxViewModel中呢?code
仍是那句话,View不处理具体的业务逻辑,View将请求交给ViewModel去处理。orm
故在FaceBoxViewModel中增长可被外界监听的委托或者事件,我以委托举例,实际上事件就是特殊的委托。
public class FaceBoxViewModel:ViewModelBase
{
//省略部分代码
public delegate void OnBeginDragHandler();
public OnBeginDragHandler OnBeginDrag;
public delegate void OnDragHandler();
public OnDragHandler OnDrag;
public delegate void OnEndDragHandler();
public OnEndDragHandler OnEndDrag;
public delegate void OnClickHandler();
public OnClickHandler OnClick;
//省略部分代码
}复制代码
FaceBoxView不处理具体的逻辑,交由FaceBoxViewModel去实现:
protected override void OnInitialize() {
//省略部分代码
//监听事件
var beginDragEntry = new EventTrigger.Entry();
beginDragEntry.eventID = EventTriggerType.BeginDrag;
beginDragEntry.callback.AddListener(eventData => { OnBeginDrag(); });
eventTrigger.triggers.Add(beginDragEntry);
var dragEntry = new EventTrigger.Entry();
dragEntry.eventID = EventTriggerType.Drag;
dragEntry.callback.AddListener(eventData => { OnDrag(); });
eventTrigger.triggers.Add(dragEntry);
var endDragEntry = new EventTrigger.Entry();
endDragEntry.eventID = EventTriggerType.EndDrag;
endDragEntry.callback.AddListener(eventData => { OnEndDrag(); });
eventTrigger.triggers.Add(endDragEntry);
var pointClickEntry = new EventTrigger.Entry();
pointClickEntry.eventID = EventTriggerType.PointerClick;
pointClickEntry.callback.AddListener(eventData => { OnClick(); });
eventTrigger.triggers.Add(pointClickEntry);
}
private void OnClick() {
if (BindingContext.OnClick != null)
{
BindingContext.OnClick();
}
}复制代码
脑海里梳理一下请求的流程:FaceBoxView.PointClick->FaceBoxViewModel.OnClick()->委托给外部的某个Handler。
实际上『委托』这个概念很是重要,和具体的语言、平台无关。好比在iOS开发常常听到代理模式,顾名思义,将请求交给具体的处理者去处理。设计模式并不深奥,不少模式的理念都是相通的,不一样的是对应语言下不一样的表现形态,善于剖开现象看本质,不少都是相通的。
源代码托管在Github上,点击此了解
欢迎关注个人公众号: