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上,點擊此了解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM