zoukankan      html  css  js  c++  java
  • Unity应用架构设计(2)——使用中介者模式解耦ViewModel之间通信

    当你开发一个客户端应用程序的时候,往往一个单页会包含很多子模块,在不同的平台下,这些子模块又被叫成子View(视图),或者子Component(组件)。越是复杂的页面,被切割出来的子模块就越多,子模块越多,彼此之间需要同步的数据和状态就越频繁,即易产生耦合。那么如何保证在复杂业务情况下,各个子模块之间可以随意通信并保持弱耦合关系,这正是本文所讨论的。

    耦合的产生

    试想一下,你有这样一下需求,点击 View A中的按钮,View B也需要做出相应的改变。

    这不是很简单吗。脑海里迅速出现两种解决方案:

    1.View A 主动通知View B做出更新,也就是View A依赖 View B

    void Notify()
    {
    	ViewB.Update(color);
    }
    

    2.View B监听View A的ColorChanged事件,主动拉取数据并更新,即ViewB 依赖View A

    ViewA.OnColorPropertyValueChanged+=(color)=>{
    	Update(color);**
    }
    

    这两种实现毫无疑问是没问题的,至少从结果上来看是正确的。但试想一下,在一个复杂的客户端单页应用程序,这种紧耦合关系会导致程序的复杂度陡然上升。每个View/ViewModel依赖其余对象,而本身又被其他View/ViewModel强引用。这显然不是好的实践方式。
    还记得我在上一篇文章的对于MVVM的描述吗?

    MVVM的核心思想就是解耦,View与ViewModel应该感受不到彼此的存在。ViewModel与ViewModel之间也应该感受不到彼此的存在。

    中介者模式的引入

    那么如何消除这种紧耦合关系呢?交给中介者设计模式来解决吧。

    我们需要添加一个中介者,每个ViewModel Publisher对象都会在自己状态改变时,告诉中介者。每个ViewModel Subscribers 都需要告诉中介者请求来时进行怎样的响应。

    在没有中介者之前对象之间都需要彼此认识,互相引用,是一种强耦合关系。有了中介者之后,彻底解耦。

    那么现在就需要定义一个中介者,称为MessageAggregator。因为由它来转发消息,所以核心是一个字典,保存了所有需要被转发的消息。它的Key为消息的唯一Id,Value代表一个对该Message的处理程序。

    public delegate void MessageHandler<T>(object sender, MessageArgs<T> args);
    public class MessageAggregator<T>
    {
        private readonly Dictionary<string, MessageHandler<T>> _messages = new Dictionary<string, MessageHandler<T>>();
    
        public static readonly MessageAggregator<T> Instance=new MessageAggregator<T>();
       
        private MessageAggregator()
        {
    
        }
       
        public void Subscribe(string name, MessageHandler<T> handler)
        {
            if (!_messages.ContainsKey(name))
            {
                _messages.Add(name, handler);
            }
            else
            {
                _messages[name] += handler;
            }
    
        }
        public void Publish(string name, object sender, MessageArgs<T> args)
        {
            if (_messages.ContainsKey(name) && _messages[name] != null)
            {
                //转发
                _messages[name](sender, args);
            }
        }
    
    } 
    

    解耦ViewModel与ViewModel###

    通过中介者MessageAggregator对象,ViewModelB Subscribe一个对消息来时的处理函数:

    MessageAggregator<object>.Instance.Subscribe("ColorChanged",ToggleHandler);
    

    ViewModel A在自己状态改变时,Pulish状态改变的消息给中介者:

    MessageAggregator<object>.Instance.Publish("ColorChanged", this,new MessageArgs<object>("Red"));
    

    小结###

    中介者模式常常用来协调相关的GUI组件,可以让对象之间传递的消息变得简单。但如果设计不当,中介者本身会变得过于复杂。
    源代码托管在Github上,点击此了解

  • 相关阅读:
    sencha touch 扩展篇之将sencha touch打包成安装程序(上)- 使用sencha cmd打包安装程序
    sencha touch 扩展篇之使用sass自定义主题样式 (下)通过css修改官方组件样式以及自定义图标
    一个不错的android组件的网站
    sencha touch 扩展篇之使用sass自定义主题样式 (上)使用官方的api修改主题样式
    sencha touch 入门系列 (九) sencha touch 布局layout
    面试题总结
    国外接活网站Elance, Freelancer和ScriptLance的介绍和对比
    sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
    Android Design Support Library——Navigation View
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/OceanEyes/p/using_message_aggregator_mediator_communication_between_viewmodels.html
Copyright © 2011-2022 走看看