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上,点击此了解

  • 相关阅读:
    python 之字符编码
    python文件处理
    迭代器和生成器
    内置函数和匿名函数
    函数之递归
    函数 之装饰器
    python 函数进阶与闭包
    python 之 函数
    python之运算符
    python字符串内置方法
  • 原文地址:https://www.cnblogs.com/OceanEyes/p/using_message_aggregator_mediator_communication_between_viewmodels.html
Copyright © 2011-2022 走看看