你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> Square對iOS App架構的新嘗試

Square對iOS App架構的新嘗試

編輯:IOS開發基礎
  • 本文由CocoaChina譯者@WhistlingArrow翻譯

  • 原文:Ziggurat iOS App Architecture


今年六月,我做了一場關於避免臃腫的ViewController的演講,用Swift講解了一種采用“單向數據流”的架構模式。當時並沒有發布相關的博客,甚至沒有給這個架構起個名字。現在兩者都有了。首先介紹一下Ziggurat:它是一種通過不可變的視圖模型和單向數據流來實現的分層的、易測試的架構模式。

QQ截圖20160125114424.png

這個架構的名字Ziggurat是根據階梯狀的金字塔得來的。像金字塔的階梯一樣,數據以數據流的形式單向地沿著App的層級傳遞,並逐層縮小。單向不可變的數據流可以減少認知負載,同時使類也變得更加瘦小。和Ziggurat相比,典型的MVC架構顯得缺少了一些指導性,對數據和狀態的操作可能散落各處,包括ViewController。

Ziggurat結合了大量討論和文章中的概念,相關內容列在了下文中更多參考部分。(劇透一下:這個架構的靈感來源於之前Facebook關於React Native的討論,並且它和Flux也很相似)。這裡提及的這些架構模式與MVC相比都是一種更好的選擇。

下面將具體介紹Ziggurat:闡述它的背景,權衡分析優缺點,定義它的組件,並通過一個例子來介紹它的用法。

MVC帶來的問題

Ziggurat是MVC的替代選擇。MVC只是簡單地將每部分的責任分離開,但並沒有將每個角色和責任分離的很清晰適當。下面是MVC帶來的常見問題:

  • 臃腫的ViewController

ViewController負責處理數據、管理I/O、請求API、包含了Model類,以及其他超出它的范圍的任務:管理視圖及UI事件。

  • 共用數據造成很難調試的Bug

誰應該處理數據?什麼時候處理數據?如果不經過精心設計,那麼答案將是誰都可以處理、什麼時候都能處理。沒有搞清這些會造成一些列的連鎖效應。

  • 太多的責任導致難以測試

沒有采用單一責任原則時會使界限變得不明確且不易發現。

在實踐中,由MVC缺少隔離導致的App沒有一種清晰地設計模式使得測試和調試bug變得非常困難。對一份代碼,不應該讓工程師們通過將一個App的設計模式和數據模型做逆向工程的方式來提高工作效率。

描述組件和單向數據流

  • 這個例子使用了這個架構模式,並且所有的組件都有說明文檔

  • 上面例子的說明文檔提供text格式文件

  • 我的臃腫的ViewController演講

  • Square工程師Kat Hawthorne的關於單向數據流的演講和幻燈片,下面是我引用其中的一張:

slide.png

上圖直觀描述了Ziggurat的單向數據流(這裡是演示)

  • 一個外部事件觸發(例如用戶輸入)

  • ViewController通知服務器它收到了用戶輸入

  • 服務器開始解析或確認此次輸入並可能對改變其狀態(只有服務器能改變其狀態)。然後調用signal()方法

  • signal()方法通知渲染器開始更新

  • 渲染器通知展示者,並生成一個View Model(服務器不會打斷循環渲染過程)

  • 渲染器將View Model 傳遞給View Controller

  • 渲染循環等待下一個外部事件觸發

權衡分析優缺點

Ziggurat架構模式解決了MVC App面臨的常見問題:

  • 臃腫的View Controller

多層的架構模式為所有功能提供了清晰的根節點,從而避免了臃腫的View Controller

  • 共用數據造成很難調試的Bug

減少了無狀態性和易變性:服務器層封裝了易變的發生(將它限制在主線程上),並且展現者和渲染都是無狀態的和單向的。使用依賴注入代替了公用狀態和全局單例。

  • 太多責任導致難以測試

更加瘦小的分層使責任分布得更均勻

帶來的改進

Ziggurat以很多方式優化了我們的生活,它使小團隊的工程師們(從沒有經驗到幾年經驗)可以在很短的期限內完成任務。

首先,它通過給工程師在面對新代碼庫時提供指導和保護性措施的方式,清晰地定義了App的層級和角色。新工程師對它的上手時間很短,因為每個組件都定義的很明確並且符合人們的直觀感覺。其次,Ziggurat模式非常易於測試。例如,可以用View Model層來將數據以目標結構輸出。這點在MVC中是無法實現的。

單向數據流避免了MVC。不可變類型,更小的類(良好的結構),更多的分層減少了工程師們的精力消耗。它可以很簡單地以輕松方式來運行你的App,因為View層中不必包含業務邏輯;所有的業務邏輯都是可測試的而不要View層;View的狀態可以通過View Model層在某一時間點的快照來重新創建。最後,我們發現這使得App變得非常輕便。多虧了這種分層的方式和依賴注入,可以輕松實現代碼移植。

帶來的問題

Ziggurat會使一些方面變得更加困難,比如動畫。我們建議在不需要很多動畫的App中使用Ziggurat。在View Controller中實現的動畫會在將來調用有關更新的方法時遭到破壞,如果不小心控制這點的話會造成界面的閃動。在Flux中,使用了React Native來解決這個問題。

此外,雖然提供了編譯期的檢查,在逐層傳遞數據時還是會帶來一些樣板代碼。並且信號數據在傳輸時會存在潛在性的瓶頸。與React不同,屬性變量不是KVO的;而是通過View Model的方式來更新屬性。這裡可能需要做一些優化,比如減少一些不需要的渲染或是調整一下你的View Model。

依賴注入需要小心地設計。我們最初的方法就導致了一張很大的由類組成的網。我們用了一些循環的依賴,導致最後不得不重構。

結論

在新項目中有機會嘗試新的想法。MVC存在很多明顯的劣勢。與此同時,一些主題的討論比如Flux、React Native、廣泛地使用Swift的值類型等正在業界形成了一股勢頭。

我們混合使用了上面的想法,用Swift寫了程序。我們感到很興奮對於使用單向數據流帶來的效果:可測試性、依賴注入、輕量級的View Controller、值類型的View Model。

這是關於Ziggurat權衡優缺點的分析,但到目前為止它仍可以很好地服務於我們。我們希望你在下一個項目中考慮采用一些這些想法(或者全部采用!),尤其是在你打算使用MVC之前。

更多參考

我看了早期的關於React的視頻,它們是Ziggurat靈感的直接來源。Flux和React Native使用了相同的概念並且是通過JavaScript實現的。

Flux是一種很強健的,以action為中心的設計模式,並且可以結合React Native一起使用。Ziggurat在涉及動畫較少的App中使用會非常容易,(Flux同樣存在這個問題,但React Native中解決了這個問題)

我們希望你在下列文章中找到Ziggurat模式的有益之處,以及一個可以代替MVC的更好方案:

  • OS Architecture Patterns

  • MVVM is Not Very Good

  • Introduction to MVVM 和 MVVM in Swift

  • Controlling Complexity in Swift

  • Introducing React Native

  • Flux (and talk)

  • Architecting iOS Apps with VIPER

  • Simple static table views for iOS in Swift

感謝Ruby Chen的插圖


  • 更多譯者翻譯文章,請查看:http://www.cocoachina.com/special/translation/

  • 本文僅用於學習和交流目的,轉載請注明文章譯者、出處和本文鏈接。 

  • 感謝博文視點對本期活動的支持

博文logo-01.jpg

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved