如何正確地寫好一個界面

寫界面能夠說是每位移動應用開發者的基本功,也是一位合格移動應用開發者繞不過去的坎。但就如不是每一位開發者都可以成爲合格的開發者同樣,本人在 不一樣的團隊中發現,甚少有人可以編寫出合格的UI代碼;而很是奇怪的是,在不少的開發者論壇上看到咱們移動開發者更多關注於某個控件或者是動畫,但卻不多 看到深刻剖析UI機制,指導UI開發的文章。html

因爲界面涉及到的方面實在過於普遍,本文不可能事無鉅細,一一道來,因此本文先立足於點,深刻剖析iOS UI系統中不被重視卻很是重要的機制,幫助本文讀者對iOS的UI系統有總體瞭解;進而以點帶面,拓展到UI邏輯設計和架構設計模式的討論;最後讀文而有 所思有所得,設計開發出高效、易用、流暢的UI模塊。前端

本文章節以下:ios

  1. 基礎與本質:說明廣泛意義上的UI系統的三大模塊,讓讀者從總體上對UI系統有清楚的認識。
  2. View:深刻View的內部機制,View與Layer之間的關係,以及Offscreen Render;
  3. ViewController:講解ViewController在UI系統中所扮演的角色,以及UI架構設計中ViewController運用和實踐;
  4. MVC、MVP、MVVM:簡單分析三種主流的架構設計模式及其異同,並簡單提出了一些作架構設計意見和想法;
  5. 總結。

各章節間沒有必然的聯繫,讀者能夠選擇感興趣章節閱讀。git



1. 基礎與本質

終端App開發區別於後端開發最大的不一樣,就是終端開發很大部分的邏輯是爲用戶提供界面以供人機交互,即所謂的UI(User Interface)。因此全部的UI架構主要關注三大模塊:界面佈局管理,渲染及動畫、事件響應;程序員

 

1.1 佈局管理

即在規定的座標系統上,按照必定的層級順序位置大小排布在容器內。一個UI系統必然有個基於座標的佈局管理系統,無論是Windows、Sysbian,仍是Andorid、iOS。好的佈局管理機制直接影響界面邏輯實現的難易程度;github

咱們如今平常接觸到的App的UI座標系統都是二維的,咱們如今玩的3D遊戲,受限於二維的展現屏幕,因此實質上只是三維在二維上的映射投影。咱們 一直在往更高的維度發展:全息影像、Hololens等等。在此能夠設想下,將來咱們構建界面的佈局管理極可能就是基於真實三維座標。數據庫

 

1.2 動畫及渲染

UI之因此叫User Interface,就是由於UI經過視覺上的展現,爲用戶提供信息。這些信息的展現須要經過一系列複雜的計算,最後操做液晶體展現在顯示屏上,這一系列過程就是渲染和動畫;後端

下圖就是應用界面渲染到展現的流程:設計模式

Render

引自WWDC2014 #419 Advanced Graphics and Animations for iOS Apps緩存

這裏不展開來說,推薦沒看過的同窗都認真觀看,可以很好的理解渲染流程和界面優化;

推薦資料:

 

1.3 事件響應

UI除了展現信息以外,還須要接收並響應用戶的點擊、手勢、搖晃等事件,通過一系列操做後更新展現信息,展現給用戶;正確及時地響應用戶的操做並給 予反饋,是良好用戶體驗的保證。爲什麼Android設備廣泛給人的感受比iOS設備要卡,其中一個主要的緣由是iOS系統將響應用戶事件放在主線程的最高 優先級。

 

1.4 UI系統架構

從總體理解了上述三個方面,你會對UI架構有系統認識。iOS中的UI系統架構以下:

iOS UI Arch

引自WWDC2014 #419 Advanced Graphics and Animations for iOS Apps



2. View

UIView是UIKit中最基本控件,就如同NSObject基本上是Cocoa庫內全部類的基類同樣,UIView也是UIKit中全部界面控 件的基類。只要你願意,你甚至只用UIView就能夠搭建你的App(不過iOS9作了約束,必須設置keyWindow的 rootViewControler)。

通常來講,熟練掌握經常使用的UIView子類控件(如UIButton, UIImageView, UILabel等)就足以應付90%的界面編碼須要。但想要編寫出高效、優美的界面代碼,還須要更深刻的瞭解。既然要深刻,本文假設你對UIView已經 有了初步的瞭解,至少使用寫過幾個完整的頁面;基於此設定下,本文討論聚焦於如下幾點:

1) UIView 與 CALayer:討論UIView背後的CALayer,瞭解CALayer與UIView的關係及渲染流程;

2) Offscreen Render:闡述什麼是Offscreen Render(離屏渲染),以及一些避免離屏渲染的方法;

3) UIResponser:討論UIView和UIViewController的父類UIResponser,分析iOS設備上的事件響應鏈;

4) 設計與實踐:結合本人開發實踐經驗,說明在UIView應用中好的設計實踐規則;

參考:View Programming Guide for iOS

 

2.1 UIView 與 CALayer

咱們應該都知道每一個UIView都包含了一個CALayer,就算你沒直接看過CALayer,應該也使用過。好比給一個View切個圓角:view.layer.cornerRadius = 5.0f;;加個邊框:view.layer.borderWidth = 1.0f; view.layer.borderColor = [UIColor darkGrayColor].CGColor;,這裏使用的layer就是CALayer。

CALayer是QuartzCore庫內的類,是iOS上最基本的繪製單元;而UIView只是CALyer之上的封裝,更準確的來 說,UIView是CALyer的簡版封裝,加上事件處理的集合類。事件處理咱們下一節再討論,這裏的簡版封裝如何理解,爲何不直接使用 CALayer?

首先,如上一段所述,CALayer是最基本的繪製單元,每個UIView都有一個CALayer的變量(public var layer: CALayer { get }),UIView的渲染實質就是這個layer的渲染。咱們能夠看看的類定義,裏面有不少屬性(變量)及方法在中能夠找到幾乎如出一轍的對應;如屬性變量framehidden,方法public func convertPoint(p: CGPoint, fromLayer l: CALayer?) -> CGPoint等;但也有更多的屬性方法是UIView所沒有的,這裏就一一列舉了。咱們能夠看到UIView實際上是把經常使用的接口(屬性和方法)暴露出來了,讓UIView更爲易用。

其次,咱們知道iOS平臺的Cocoa Touch 是源於OS X平臺的Cocoa), 是在Cocoa的基礎上添加了適用於移動手機設備的手勢識別、動畫等特性;但從底層實現上來講,Cocoa Touch與Cocoa共用一套底層的庫,其中就包括了QuartCore.framework;但QuartCore.framework一開始就是爲 OS X設計的,因此其中有部分特性是不適合作移動設備開發的,好比最重要的座標系統。所以,咱們也就不難理解爲什麼UIView/NSView在CALayer 上作了一層封裝。

以上,是UIView於CALayer的主要的關係。

 

2.2 Offscreen Render

當你尚在懵懂未知的開發初期,在寫UIScrollView及其子類(UITableView、UICollectionView)時,必定會遇到 滾動不流暢,常常卡頓的狀況;你認真研究代碼,發現你邏輯代碼都放到了異步線程,主線程作的都是渲染界面的活,爲何會卡頓?而後你想老手尋求幫助,老手 會讓你去掉圓角、半透明和陰影之類,App又重回絲般順滑;你不知道爲何,問老手,他可能會很詳細跟你解釋一通,而後你只知其一;不知其二地點點頭,腦中一片茫 然;較好的狀況,也許你依稀記得這麼一個詞:離屏渲染(Offscreen Render)。那到底什麼是Offscreen Render?爲何Offscreen Render會致使卡頓?

在第一章的1.2節中有提到渲染的流程圖,咱們再更深刻點,先看看最基本的渲染通道流程:


iOS UI Arch

引自WWDC2014 #419 Advanced Graphics and Animations for iOS Apps

注:iOS的GPU渲染機制是Tile-Based的,而Tile-Based GPU也是如今移動設備的主流;

咱們再來看看須要Offscreen Render的渲染通道流程:


iOS UI Arch

引自WWDC2014 #419 Advanced Graphics and Animations for iOS Apps

通常狀況下,OpenGL會將應用提交到Render Server的動畫直接渲染顯示(基本的Tile-Based渲染流程),但對於一些複雜的圖像動畫的渲染並不能直接渲染疊加顯示,而是須要根據 Command Buffer分通道進行渲染以後再組合,這一組合過程當中,就有些渲染通道是不會直接顯示的;對比基本渲染通道流程和Masking渲染通道流程圖,咱們可 以看到到Masking渲染須要更多渲染通道和合並的步驟;而這些沒有直接顯示在屏幕的上的通道(如上圖的 Pass 1 和 Pass 2)就是Offscreen Rendering Pass。

Offscreen Render爲何卡頓,從上圖咱們就能夠知道,Offscreen Render須要更多的渲染通道,並且不一樣的渲染通道間切換須要耗費必定的時間,這個時間內GPU會閒置,當通道達到必定數量,對性能也會有較大的影響;

那哪些狀況會Offscreen Render呢?

1) drawRect
2) layer.shouldRasterize = true;
3) 有mask或者是陰影(layer.masksToBounds, layer.shadow*);
4)Text(UILabel, CATextLayer, Core Text, etc)
...

注:layer.cornerRadius,layer.borderWidth,layer.borderColor並不會Offscreen Render,由於這些不須要加入Mask。

還有更多與Offscreen Render以及動畫圖形優化相關的知識,請認真觀看WWDC。

參考:

 

2.3 設計與實踐

以上幾節,對View在開發過程當中常常遇到,但並不容易深刻理解的概念進行了討論。接下來,我想脫離View的具體概念,談談本人在View設計和開發中的一些實踐經驗;

 

2.3.1 精簡扁平的View層次結構

複雜的View層次結果不只會影響渲染效率,並且也會形成代碼的臃腫,會形成不可預料的問題而且難以定位;怎麼樣維護一個精簡扁平的View層次結構呢?原則以下:

1) 儘可能使用系統原生的控件;

如實現一個icon跟title上下佈局的按鈕,不少人習慣是使用一個view包含了一個UIButton和一個UILabel。實際上更爲推薦的 方式是調整UIButon的contentInset/titleInset/imageInset三個參數來達到這個效果,很是簡單,而且title有 UIButton上的展現方式和特性,如能夠設置高亮顏色等;

又好比一個有着複雜一點佈局結構的滾動界面,有些開發者會以爲使用UITableView/UICollectionView實現會比較複雜,有些 效果可能沒辦法達到,就用他們的基類UIScrollView來實現,本身造了一大套的輪子,代碼可能也變得很是複雜;實際上根據個人經驗,經過重寫或者 是內部屬性的調整是徹底可使用UITableView/UICollectionView來達到這個效果,畢竟UITableView /UICollectionView是UIScrollView的子類,功能不會減小,而會更增強大,而且咱們還能利用已有的data source和delegate機制,實現設計上的解耦。

其餘常見的還有UINavigationBar、UITabBar、UIToolBar等等;


2) 合理添加/刪除動態View;

有些View是動態的,就是偶爾顯示,偶爾隱藏。這類View有兩種處理方式:增刪,或者顯示/隱藏。沒有標準的答案,我的更推薦增刪的處理方式, 即在有須要的時候添加到對應的ContainerView上,在不須要的時候將其刪除。這樣便可以與懶加載結合在一塊兒,並且也能避免兩個動態View的相 互影響,好比TableFooterView,或者是錯誤加載View。但這並非惟一的方式,假如這個動態View所在的View層級比較簡單,而且需 要動畫進行動態展現,則使用顯示/隱藏也是不錯的處理方式。

 

2.3.2 通用控件;

每個程序員均可以創建本身的代碼庫,同理,每一位移動開發程序員均可以創建本身的通用控件代碼庫。這個庫內的控件,能夠是你本身寫的,也能夠是優 秀的第三方開源控件。創建控件庫,除了可以避免從新造輪子,大大提升咱們的開發效率,還有更爲重要的一點:在運用、改造、重構中掌握接口設計解耦,甚至是 架構的知識和經驗。

每一個App的UI設計、交互、佈局和配色每每千差萬別,但總脫離不出移動App這一範疇,也就決定了在某些通用的控件交互上會保持一致性,以讓用戶 依據本身在移動應用上的使用經驗就能輕鬆快速上手使用,這就是App的移動性。因此通用控件的適用場景每每是很「通用」的。好比下拉刷新、加載更多、 Tab Bar、提示Tips、加載錯誤從新加載等等。在新的App或者功能模塊上運用這些控件時,你就會思考怎麼讓控件更加通用,即不影響舊的邏輯,又可以適用 新的需求,這對於作界面的架構設計是很是好的鍛鍊。

 

2.3.3 合理運用VC在替代View組合複雜界面;

在界面開發過程當中,咱們經常會遇到複雜的界面,好比多頁界面、多種佈局方式展現多業務的首頁等,但因爲很大部分開發者已經對「一屏就是一個VC」這 一初學者的習慣奉爲教條,寫出一個龐然大View,再加上覆雜的邏輯代碼,這一塊的代碼極可能就演變成了誰都不敢動的禁區。一個VC能夠管理多個VC,所 以合理的使用VC來替代View進行復雜界面組合,不只可以將複雜界面切分紅更小的粒度,邏輯代碼也同步合理劃分,便於維護和重構;而依託VC的機制,還 能View和數據的動態加載管理。

下一章中關於輕VC的討論是這一節知識的拓展。



3. ViewController

上一節關於View的章節已討論了iOS界面機制,這一節則主要是來談談在寫界面過程當中的設計問題和基本規範;

ViewController在iOS只是一個很是重要的概念,它是咱們在開發界面時最常打交道的模塊,其在一個App中所扮演的角色,View Controller Programming Guide for iOS 中有清晰準確的描述:

1) View Management:管理View;

2) Data Marshalling:管理數據;

3) User Interactions:響應用戶交互;

4) Resource Management:管理資源;

5) Adaptivity:適配不一樣的屏幕尺寸空間的變化;

能夠看到,ViewController有太多的事情要作,這也就致使了ViewController很是容易變得代碼膨脹、邏輯混亂等問題;依照 我的經驗,一個ViewController類的有效代碼超過500行,這個ViewController就會變得難以維護,但實際上在開發過程當中,每每 會遇到上1K行,甚至2~3K行的ViewController類;當一個ViewController類達到2~3K行,就意味着其餘開發者接手這個模 塊來修改東西,已經沒法經過滾動來定位代碼,只能經過搜索;

因此,在進行界面開發時,ViewController須要特別注意模塊設計,將不一樣的模塊按照邏輯進行必定的拆分,即解耦,又防止ViewController模塊的代碼膨脹。這就是輕VC的理念;

 

3.1 輕VC

輕VC是前兩年很是火的名詞,如今彷佛已經成爲了一種業界規範或者是慣例。同上所述,一個VC的類,若是有效代碼超過了500行,則表示這個類看是變得臃腫而難以維護;到達800行,只能經過搜索來定位代碼時,重構已勢在必行;

關於輕VC,objc.io的開篇第一章#Issue 1 : Lighter View Controllers,足見這一理念的重要性。掌握輕VC的理念基本上是一個iOS開發者從初級邁向高級必備技能。#Issue 1 : Lighter View Controllers 文中介紹了構建輕VC幾種常見的方式:

1) 將數據源等複雜接口從VC中剝離;

2) 把業務邏輯代碼抽象到Model層;

3) 將複雜View抽象成獨立的類;

4) 使用VC的Containment的特色,將一個VC中邏輯分離的界面模塊剝離成爲多個子VC;

想要設計出合理而易於理解和維護的輕VC結構,須要掌握輕VC的知識並有必定實踐經驗。在如下狀況下,能夠考慮將一個VC設計或者重構成更多模塊更多類的輕VC結構:

1) 如上所述,代碼超過500行時;

2) VC內的View的數據源來自多個不一樣的地方;

3) VC內有多個複雜的View,須要展現數據實體類較爲複雜;

總之,當你感受你的VC已經變得臃腫,那麼就可嘗試輕VC的實踐,實踐纔有收穫。

 

3.2 VC的設計

相對於View關注於佈局和展現,VC更關注設計和管理。本節以一個實例,來簡單介紹在一個完整App中的VC設計。

先來看一個常見的UI結構設計例子:


iOS UI Arch

這個圖應該很是容易理解:最底部是一個側滑抽屜控件,該抽屜包含了App內容展現的TabBarController和設置的 VC;TabBarController的子Item VC包含了相應業務的List VC,點擊List VC進入到詳情View內;有些詳情VC是使用WebViewController來進行內容的展現。很是簡單,不是麼?接下來講明該設計的洞見:

1) Root ViewController,是整個App內Window的根VC,這是一個生命週期與 App相同的VC,即Window的RootViewController是惟一且一直存在的,須要切換場景則使用這個Root VC控制子VC切換來實現(常見於場景:須要進行強登陸,即登陸以後才能使用的App,登陸成功後從登陸界面切換到主界面,則登陸VC和主界面VC都應該 是Root VC的子VC,受Root VC的控制來進行切換)。這個RootViewController建議是一個UINavigationController,以此保證足夠擴展性,並提 供更爲豐富的界面交互選擇。這個Root VC的生命週期與App一致,這樣一些突發的靈活分支界面能夠很好的展現在Root VC上,如全局的Loading提示、OpenURL的分支調整等;

2) Main ViewController:主界面,是主要業務展現界面的根界面。該VC與RootVC功 能上會很容易重合在一塊兒,但須要注意的是,該VC並不是一直存在,但切換到一些特定分支時,該VC會從Root VC上remove掉,好比前面所說的強登陸App,登陸界面與主界面就會須要進行切換。另外,該VC隔離了主要業務展現界面的VC與Root VC,便於App總體界面風格的改版和重構。好比如今上圖展現的是一個側滑抽屜+TabBar的組合,那到下個版本改版把側滑抽屜去掉,那麼只須要使用 TabBar替換DrawerMenu VC在Main VC中的位置便可,而不會影響到RootVC中其餘分支展現出來的界面(如Push等)。

3) TabBarItem ViewController:做爲TabBar Controller的子Item VC,一般會設計爲NavigationController,用以管理各TabBarItem內的VC棧。 注:若是須要在Push進入二級界面(Detail VC)時隱藏TabBar,只須要設置二級VC的hidesBottomBarWhenPushed = true便可,若是想更加靈活的控制TabBar,例如進到三級頁面的時候顯示出TabBar(這個場景應該不多見),或者你的TabBar是自定義的,能夠參考我寫的一個開源控件MZNavTab

本節所示例的UI結構是一個很是通用的UI結構,市面上除遊戲外60%以上的App都是相似的UI交互(統計來源於我的手機),假如你的UI交互與此相似而你的UI結構很混亂的話,不如嘗試下這個UI結構設計。

 

4. MVC、MVP、MVVM

MVC


iOS UI Arch

MVP


iOS UI Arch

MVVM


iOS UI Arch

圖注: 虛線箭頭:表示二者之間是非強依賴關係。如MVC圖,View與Model通常沒有直接聯繫。

虛線矩形:表示該模塊在對應架構設計中的隱性存在。即通常性架構中並無這個角色,但立足於iOS這個平臺,這又是不可或缺的一部分;

本文並不打算將MVC、MVP、MVVM這個幾個通用架構設計模式的概念通通在這裏敘述一遍,上面三個圖基本上可以很明白地對比出三者之間的差別。也許與你在網上看到的不盡相同,這是由於以上三圖更立足於iOS平臺。

 

4.1 MVC

咱們最初看到的MVC設計模式圖多是這樣的:


iOS UI Arch

引自[MSDN#ASP.NET - Single-Page Applications: Build Modern, Responsive Web Apps with ASP.NET(https://msdn.microsoft.com/en-us/magazine/dn463786.aspx)

而蘋果官方給的MVC的設計模式圖倒是這樣的:


iOS UI Arch

到底哪一副圖纔是真正的MVC?個人答案只能是:都是。

MVC從施樂帕克實驗室提出至今,已經應用到各類應用開發領域中:Web App能夠用MVC,iOS/Android/Windows客戶端應用也用MVC,Web前端也在用MVC,等等;這些幾乎涵蓋了咱們常見的開發領域, 因此MVC其實已經超越了他本來最初的設計,基於全部涉及展現的應用都能套上MVC,只不過不一樣的平臺在設計上略有差異。而MVP和MVVM,也不過是 MVC的衍生變種,除這二者以外,還有咱們沒怎麼見過的HMVCMVA等。

 

4.2 Model Layer

在討論MVP和MVVM以前,我想先明確一個常常被誤解的概念:Model。因爲Model這個詞太通用化,如數據Model,數據庫Model,這就致使了Model這一律念理解差別化,簡單的說,就是被玩壞。拋開其餘,咱們來看看常見的定義:

Wikipedia的定義

The central component of MVC, the model, captures the behavior of the application in terms of its problem domain, independent of the user interface.[11] The model directly manages the data, logic and rules of the application.

MSDN(https://msdn.microsoft.com/en-us/library/ff649643.aspx)中的定義

Model. The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

上面兩個定義基本一致:Model,管理應用的行爲和數據。

再來看看Apple官方文檔Model-View-Controller的定義

Model Objects

Model objects encapsulate the data specific to an application and define the logic and computation that manipulate and process that data. For example, a model object might represent a character in a game or a contact in an address book. A model object can have to-one and to-many relationships with other model objects, and so sometimes the model layer of an application effectively is one or more object graphs. Much of the data that is part of the persistent state of the application (whether that persistent state is stored in files or databases) should reside in the model objects after the data is loaded into the application. Because model objects represent knowledge and expertise related to a specific problem domain, they can be reused in similar problem domains. Ideally, a model object should have no explicit connection to the view objects that present its data and allow users to edit that data—it should not be concerned with user-interface and presentation issues.

Communication: User actions in the view layer that create or modify data are communicated through a controller object and result in the creation or updating of a model object. When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects.

雖然Apple的官方文檔是定義Model Objects,但它的含義仍是封裝數據以及管理數據相關的邏輯計算;

因此這裏須要明確的一個概念是:在MVC的設計模式中,Model是一個Layer,而不僅是一個數據模型(Data Model)類。整體來講,Model Layer 包含了數據模型,以及管理這些數據相關的邏輯計算,如本地數據變化、數據緩存、從網絡請求數據等業務邏輯。關於這個問題,還能夠參考這篇文章:《iOS應用架構談 view層的組織和調用方案》。 但有一點須要說明:該文章更傾向於從Model Object上思考Model的定義,由於裏面的關於Model的示例是從數據模型中擴展出業務接口;而本人則更傾向於從Model Layer來思考Model,即Model並不限於數據模型,能夠是數據管理類(各類Manager)、請求隊列管理等等。

 

4.3 MVP VS MVVM

上一節關於Model Layer中推薦的文章《iOS應用架構談 view層的組織和調用方案》對MVC和MVVM都作了很是詳細的討論,是一篇很是不錯的文章,推薦各位閱讀,那麼本節就來講說MVP,以及我爲何更傾向於選擇MVP做爲App架構設計中的設計框架。

回顧下在本章一開始祭出的MVP以及MVVM兩張圖,二者之間有什麼不一樣?

MVVM的VM(View Model)到V(View),比MVP的P(Presenter)到V(View),多了數據綁定。也就是

MVP: 是MVC的變種,其中Model和View的定義與MVC的一致,不一樣點在於:MVC的Controller是管理一組Model與View之間交互邏 輯,是一個管理者;而Presenter(展現者)則是Model於View之間的鏈接者,針對特定模塊的View提供對應的格式化的Model數據,將 View中的行爲反饋到Model中。因此MVC中的Controller通常會管理一個或多個Model和一個或多個View,而Presenter則 是 M-P-V 一對一,有更細的粒度和更好的解耦。

從MVP的定義,你會發現MVP與MVVM極其類似,Presenter與View Model扮演的角色基本沒有差異,除了前面所說到綁定機制。但綁定機制既有很明顯的強大優勢——自動鏈接View和Model,也有很明顯的缺點——更 高的耦合度,更復雜的代碼邏輯;但讓人感嘆命運無常的是:MVVM隨着ReativeCocoa而在iOS平臺煊赫一時,而iOS平臺上甚少有人說起的 MVP,在Android平臺卻幾乎成了標準(Android5.0引入了數據綁定支持,MVVM會在Android平臺有新的發展)。

我爲何傾向於MVP?不過是相比於MVVM雙向綁定的便利,我更但願個人App設計中有更強的靈活性和擴展性。沒有完美的架構設計模式,只有適用 於你的App業務場景和團隊的設計模式。好比數據邏輯並不複雜、更注重視覺展現的應用,原始的MVC每每是最優解。全部的MVC衍生出的變種,無非是爲了 Solve The Problem。

 

4.4 架構設計模式應用

不管MVC、MVP仍是MVVM,都是指導咱們進行架構設計的模式,並不是能夠生搬硬套的;並且在實際的應用中,對於這些設計模式總會有不一樣的理解, 而且須要根據項目需求進行必要的調整;更爲重要的是在咱們App的架構設計中,處理好Model-View-Controller之間的關係只是基礎,最 主要的挑戰來自於複雜的業務邏輯和場景,這纔是體現一個架構師能力所在。

唐巧前不久寫的一篇文章《被誤解的MVC和被神化的MVVM》對MVC和MVVM的實踐的討論應該是體現瞭如今移動端主流架構思想,其中對網絡請求層、ViewModel 層、Service 層、Storage 層等其它類的提取設計,才決定了一個App架構設計的優劣。

對於架構設計,我準備在下一篇文章,結合本人在iOS/Android兩端的設計經驗,作個深刻的討論,並給出本身的設計範例,供各位討論參考。這裏先拋出幾個在架構設計中最常思考的點,做爲下一篇文章的引子:

1) 架構是爲了解耦,越鬆的耦合就表明越多的份層,但人的思惟老是更願意接受直線思惟,怎麼解決這個矛盾?

2) 在一個App中,統一(一致)的架構設計可以讓邏輯代碼更健壯,更有利於團隊成員間的溝通和項目維護,但如何解決其和靈活性之間的矛盾?

3) 架構設計是否只包含邏輯分層?須要設計數據流和多線程麼?

4) 設計模式中的幾大原則;



5 總結

以上四個章節,先從UI總體出發,到剖析UIView幾點重要機制,接着討論怎麼用好VC這個UI中重要的管理角色,最後則漫談了MVC/MVVM /MVP幾個架構設計模式的異同和實踐應用,想經過以點帶面,讓咱們在關注了具體實現以後,可以脫離出來,從俯視下咱們App開發更爲總體核心的部分。



參考閱讀:

相關文章
相關標籤/搜索