MVC架構介紹

每個程序員都知道的最流行的應用程序架構是MVC。MVC 代表模型-視圖-控制器

這與其說是應用程序的架構,不如說是應用程序組件的架構,但我們稍後會回到這個細微差別。什麼是 MVC?

MVC 是一種將應用程序數據和控制邏輯分離為三個獨立組件(模型、視圖和控制器)的方案,以便每個組件都可以獨立修改。

  • 模型(Model)通過改變其狀態來提供數據並響應控制器命令。
  • 視圖負責向用戶顯示模型數據以響應模型更改。
  • 控制器(Controller)解釋用戶的動作,通知模型需要改變。

該模型是在 1978 (!) 年發明的。是的,適當的軟件架構問題在 50 年前就已經存在。以下是原始圖表描述此模型的方式:

MVC架構介紹

該模型提供數據和使用它們的方法:查詢數據庫、檢查正確性。該模型獨立於視圖(不知道如何呈現數據)和控制器(沒有用戶交互點),提供對數據的訪問和管理。

該模型的構建方式是通過改變其狀態來響應請求,並且可以內置“觀察者”的通知。由於獨立於視覺表示,模型可以對一個“模型”有多個不同的表示。

視圖負責從模型中獲取所需的數據並將其發送給用戶。該視圖不處理用戶輸入。

控制器提供用戶和系統之間的“通信”。控制和引導數據從用戶到系統,反之亦然。使用模型和視圖來實現所需的操作。

該模型在過去幾十年中有所發展,這一事實存在一定的困難。也就是說,名稱保持不變,但部件的用途開始發生變化。

Web 上的 MVC 架構

MVC 設計模式背後的思想非常簡單:我們需要明確區分應用程序中不同行為的責任:

模型——數據處理和應用邏輯。

看法——以任何支持的格式向用戶提供數據。

控制器- 處理用戶請求並調用適當的資源。

該應用程序分為三個主要組件,每個組件負責不同的任務。讓我們通過一個示例來更深入地了解客戶端-服務器應用程序的組件。

控制器

用戶在瀏覽器中單擊頁面上的各種元素,結果瀏覽器發送各種 HTTP 請求:GET、POST 或其他。控制器可以包括在頁面內工作的瀏覽器和 JS 代碼。

在這種情況下,控制器的主要功能是調用必要對象的方法,管理對資源的訪問以執行用戶指定的任務。通常,控制器為任務調用適當的模型並選擇適當的視圖。

模型

廣義上的模型是數據和用於處理數據的規則——它們一起構成了應用程序的業務邏輯。設計應用程序總是從構建它所操作的對象的模型開始。

假設我們有一家賣書的在線商店,那麼一個人只是應用程序用戶還是一本書的作者?在模型設計期間必須解決這些重要問題。

此外還有規則集:可以做什麼,不能做什麼,哪些數據集可以接受,哪些不可以。一本書可以沒有作者嗎?沒有書的作者呢?用戶的出生日期是否可以在 300 年等等。

該模型為控制器提供了用戶請求的數據(消息、書頁、圖片等)的視圖。無論我們想如何將其呈現給用戶,數據模型都是相同的。因此,我們選擇任何可用的視圖來顯示數據。

該模型包含我們應用程序邏輯中最重要的部分,即解決我們正在處理的問題(論壇、商店、銀行等)的邏輯。控制器主要包含應用程序本身的組織邏輯(就像您的項目經理一樣)。

看法

視圖提供了多種方式來表示從模型接收到的數據。它可以是一個填充有數據的模板。可以有幾種不同的視圖,控制器會選擇最適合當前情況的一種。

Web 應用程序通常由一組控制器、模型和視圖組成。控制器只能在後端,但當其邏輯也分佈在前端時,也可以有多個控制器的變體。這種方法的一個很好的例子是任何移動應用程序。

網絡上的 MVC 示例

假設您需要開發一家銷售書籍的在線商店。用戶可以執行以下操作:查看書籍、註冊、購買、將項目添加到當前訂單、標記他喜歡的書籍併購買。

您的應用程序應該有一個負責所有業務邏輯的模型。您還需要一個控制器來處理所有用戶操作並將它們轉換為來自業務邏輯的方法調用。但是,一個控制器方法可以調用許多不同的模型方法。

您還需要視圖集:書籍列表、關於一本書的信息、購物車、訂單列表。Web 應用程序的每個頁面實際上都是一個單獨的視圖,向用戶顯示模型的某個方面。

讓我們看看如果用戶打開書店推薦書籍列表來查看書名會發生什麼。整個動作序列可以用 6 個步驟的形式描述:

網絡上的 MVC 示例

腳步:

  1. 用戶點擊“推薦”鏈接,瀏覽器向/books/recommendations發送請求。
  2. 控制器檢查請求:用戶必須登錄。或者我們應該為未登錄的用戶收集書籍。然後控制器調用模型並要求它返回推薦給用戶 N 的書籍列表。
  3. 該模型訪問數據庫,從那裡檢索有關書籍的信息:當前流行的書籍、用戶購買的書籍、他的朋友購買的書籍、他的願望清單中的書籍。基於這些數據,模型構建了一個包含 10 本推薦書籍的列表,並將它們返回給控制器。
  4. 控制器收到推薦書籍列表並查看它。在這個階段,控制器做出決定!如果書籍很少或列表完全為空,則它會為未登錄的用戶請求書籍列表。如果現在正在進行促銷,則控制器可以將促銷書籍添加到列表中。
  5. 控制器決定向用戶顯示哪個頁面。它可以是一個錯誤頁面,一個包含書籍列表的頁面,一個祝賀用戶已成為第 100 萬名訪問者的頁面。
  6. 服務器向客戶端提供控制器選擇的頁面(視圖)。它填充了必要的數據(用戶名、書籍列表)並發送給客戶端。
  7. 客戶端接收頁面並將其顯示給用戶。

這種方法有什麼好處?

我們從使用 MVC 概念中獲得的最明顯的優勢是表示邏輯(用戶界面)和應用程序邏輯(後端)的明確分離。

第二個優勢是將服務器部分分為兩部分:智能模型(執行器)和控制器(決策中心)。

在前面的例子中,有一段時間控制器可以從模型中收到一個空的推薦書籍列表,並決定如何處理它。理論上,可以將此邏輯直接放入模型中。

首先,在請求推薦書籍時,如果列表為空,模型將決定做什麼。然後我將不得不在同一個地方添加代碼,如果現在正在進行促銷該怎麼辦,然後有更多不同的選擇。

後來發現店主想看看沒有促銷的情況下用戶的頁面會是什麼樣子,反之亦然,現在沒有促銷,但他想看看以後的促銷會如何顯示。並且沒有為此的方法。因此,決定將決策中心(控制器)與業務邏輯(模型)分開。

除了將視圖與應用程序邏輯隔離之外,MVC 概念還大大降低了大型應用程序的複雜性。代碼更加結構化,更易於維護、測試和重用解決方案。

了解 MVC 的概念,作為開發人員,您會意識到需要在何處添加對圖書列表進行排序:

  • 在數據庫查詢級別。
  • 在業務邏輯(模型)級別。
  • 在業務邏輯層(控制器)。
  • 在視圖中 - 在客戶端。

這不是一個修辭問題。現在,想一想您需要在何處以及為何需要添加用於對圖書列表進行排序的代碼。

經典 MVC 模型

MVC 組件之間的交互在 Web 應用程序和移動應用程序中的實現方式不同。這是因為 Web 應用程序是短暫的,處理一個用戶請求並退出,而移動應用程序處理許多請求而無需重新啟動。

Web 應用程序通常使用“被動”模型,而移動應用程序使用“主動”模型。與被動模型不同,主動模型允許您訂閱和接收其中更改的通知。Web 應用程序不需要這樣做。

這是各種模型中組件交互的樣子:

經典 MVC 模型

移動應用程序(主動模型)主動使用事件和事件訂閱機制。使用這種方法,視圖 ( view ) 訂閱模型更改。然後,當某些事件發生時(例如,用戶單擊按鈕),將調用控制器。它還為模型提供了更改數據的命令。

如果某些數據已更改,則模型會生成有關更改此數據的事件。所有訂閱此事件的視圖(更改此特定數據很重要)都會收到此事件並更新其界面中的數據。

在 Web 應用程序中,事物的組織方式略有不同。主要的技術區別是客戶端不能主動接收服務器端的消息

因此,Web 應用程序中的控制器通常不會向視圖發送任何消息,而是給客戶端一個新頁面,從技術上講,這是一個新視圖甚至是一個新的客戶端應用程序(如果一個頁面對另一個頁面一無所知) .

目前,使用以下方法部分解決了此問題:

  • 定期輪詢服務器以了解重要數據的更改(每分鐘一次或更長時間)。
  • WebSockets 允許客戶端訂閱服務器消息。
  • 來自服務器端的 Web 推送通知。
  • HTTP/2 協議允許服務器發起向客戶端發送消息。