[Android]一個乾凈的架構(翻譯)

来源:http://www.cnblogs.com/tiantianbyconan/archive/2016/03/14/5276587.html
-Advertisement-
Play Games

以下內容為原創,歡迎轉載,轉載請註明 來自天天博客: 一個乾凈的架構 原文: 在過去幾年中我們能看到的一系列關於系統架構的思想。它們包括: [Hexagonal Architecture](也稱為 ),作者是 Alistair Cockburn,並被 Steve Freeman 和 Nat Pryc



以下內容為原創,歡迎轉載,轉載請註明
來自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5276587.html

一個乾凈的架構

原文:https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

在過去幾年中我們能看到的一系列關於系統架構的思想。它們包括:

儘管這些書在細節上有些不同之處,但是它們是非常相似的。從分離的觀點上來講它們都有著同樣的目標。它們都是通過軟體分層來實現分離的。每一個都至少有一層是用於業務規則,另外一層用於介面。

這些架構生產系統:

  1. 框架獨立性。架構並不依賴於已經存在的某些庫的有負載的特性。這允許你作為工具去使用框架,而不是把你的系統強塞到限制和約束中。

  2. 可測試性。業務規則可以脫離UI、資料庫、web伺服器和其它外部元素去進行測試。

  3. UI的獨立性。UI可以在不修改系統其它地方的情況下很容易地被改變。比如,一個Web UI可以使用console UI替換,而不改變任何業務規則。

  4. 資料庫獨立。你可以使用Mongo、BitTable、CouchDB或者其它來置換Oracle或SQL Server。你的業務規則不會被資料庫束縛。

  5. 外部代理的獨立性。事實上,你的業務規則根本不知道外面的世界。

這篇文章頂部的圖表就是嘗試所有這些結構到單個可操作的思想中去。

依賴準則

同心圓表示不同軟體的區域。一般情況下,走得越遠,軟體水平也會變得越高。外面的圓是機制,而內部的圓是政策。

使得這個架構可行的最重要的規則是 依賴準則 。這個準則指 代碼的依賴 只能 向內 。沒有一個內部圓可以知道外部圓的任何東西。尤其是在內部圓聲明的東西名字不能被內部圓中的代碼提到。這裡包括方法、類、變數、或者其它軟體實體的名字。

同樣的原因,外部圓中用到的數據格式不能被內部圓使用,尤其是這些格式是被外部圓中的框架生成的。我們不希望任何在外部圓中的東西影響到內部圓。

Entities

實體封裝了 企業級 業務規則。一個實體可以是一個有方法的對象,或者有一系列的數據結構和函數。只要這個實體可以被很多不同企業中的應用使用就沒關係。

如果你沒有一個企業,並且只是編寫單個的應用程式,那麼這些實體就是應用程式中的業務對象。它封裝了大部分一般的和高級別的規則。它們最不可能在外部改變的時候被改變。比如,由於安全你不希望這些對象被導航頁面改變而影響。沒有特別的可操作的改變可以影響實體層。

用例

軟體在這一層包含應用程式指定的業務規則。它封裝和實現了這個系統的所有用例。這些用例轉化數據流到實體和從實體轉化到數據流,然後這些實體直接使用它們企業範圍的業務規則來達到用例的目的。

我們不期望改變這一層來影響到實體。我們也不希望這一層被外部的改變,比如資料庫、UI、任何常見的框架等影響。在這一層在這的觀點上是被孤立的。

然而,我們要做的是希望應用程式操作的改變會影響到軟體的用例,所以應該是在這一層。如果用例的細節改變了,那麼這一層的某些代碼當然也會受到影響。

介面適配器

在軟體的這一層是一系列的適配器,通過最方便的用例和實體轉換數據格式,最方便的外部代理格式有資料庫或者Web等。在這一層,舉個例子,將會完整包含 GUI 的 MVC 架構。Presenters、Views、 Controllers 都屬於這裡。Models有可能僅僅是數據結構,它們從 contrllers 被傳入到用例中,然後從用例到 presenters 和 views。

同樣的,在這一層,數據會被轉換,從最方便的方式如實體和用例,轉換到使用的用於持久框架的最方便的方式,即資料庫。
這個圓中沒有代碼可以向內知道任何關於資料庫的東西。如果資料庫是一個 SQL database,那麼所有 SQL 應該在這一層被限制,特別是在這一層需要進行資料庫操作的部分。

在這一層也有必要從一些外部形式去轉換數據,比如一個外部服務,轉化為內部用例和實體使用的形式。

框架和驅動

最外層通常是框架和工具,通常是資料庫、Web 框架等的組合。通常你不需要在這一層編寫太多的代碼,除了一些用於向內圈進行通信的固定代碼。

這一層是所有細節走向的地方。Web是一個細節。資料庫是一個細節。我們把這些東西放置在外部,這樣它們就難以造成傷害。

只有四個圓?

不,這些圓只是簡圖。你可能會需要多於這四個圓。這裡並沒有一個規則來讓你必須要使用這四個圓。然而,依賴規則 總是適用的。代碼依賴總是指向內部。當你向內移動時,抽象級別增加。最外層的圓是最低級別的具體細節。當你向內移動,就會變得更加抽象和更高級別策略的封裝。最內部的圓是最通用的。

跨越邊界

右下方的圖是一個我們怎麼去跨越圓的邊界的例子。它展示了 Controllers 和 Presenters 通過下一層使用用例進行通信。註意控制流。它在controller中開始,通過用例,然後再Presenter中執行。也要註意代碼的依賴。它們每一個都是向內指向用例。

我們通常使用 依賴反轉準則 來解決這個明顯的矛盾。在像Java的語言中,舉個例子,我們使用了interfaces和繼承關係,這樣代碼依賴關係控制權被反轉,達到跨越邊界的目的。

舉個例子,考慮到用例需要調用Presenter。然而,這些調用必須不能是直接的,因為它會違反_依賴準則_:內部圓不能提到外部圓中的任何名字。所以我們這種情況我們會調用在內部圓中的介面(就像這裡展示的 Use Case Output Port)),然後在外部圓中的Presenter去實現它。

同樣的技術在架構的所有跨越邊界的地方被使用到。我們利用動態代理的優勢去創建代碼依賴來達到控制反轉,所以我們可以確保無論什麼方向的 依賴準則 控制流都能有效。

什麼數據跨越邊界。

典型的跨越邊界的數據就是簡單的數據結構。如果你喜歡你可以使用基本結構或者簡單的數據傳輸對象。或者是方法調用時的簡單的參數數據。或者你可以把它放進一個HashMap,或者構建它到一個對象中。重要的是分離的、簡單的數據結構跨越過邊界。我們不希望去欺騙並傳遞 Entities 或者資料庫的行。我們不希望數據結構有任何的違反 依賴準則 的依賴。

舉個例子,很多資料庫框架通過一個查詢返回一個方便的數據形式的響應。我們可能稱它為一個RowStructure。我們不希望這個行結構向內跨越邊界。這將違反 依賴準則 因為這將強制一個內部圓去知道外部圓的一些東西。

所以當我們跨越邊界傳遞數據時,它對於內圓來說總是以最方便的形式的。

遵守這些簡單的規則並不難,前進的道路上會解決很多頭疼的事情。通過分離軟體到不同層次,並遵守 依賴準則 ,你將會創建一個本質上可測試的系統,這意味這所有的好處。當任何系統外置的部分變得過時,就像資料庫,或者web框架,你可以在最小的改動下替換這些外置元素。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個基於redis的處理session的方法,如下。 補充: php.ini文件中的session.gc_probability與session.gc_divisor兩個配置選項共同決定gc函數調用的時機。預設值分為為1和1000,表示每個請求只有1/1000的機會調用gc函數。
  •     問題的產生,必有其理由。說白點也就是客戶需要,沒辦法的事。不過也到給我們添了不少麻煩。本人也希望大牛們能給在下提提更多的思路,在下在此謝過。     具體是這樣:   1.要記錄操作人員,操作時間,操作相應模塊          2.要記錄操作的原始數據(ps:列級別)和變更後數據    
  • 前言:OpenCV對圖像及視頻的處理方便且很專業,對於攝像頭的支持也很好,但有個不足就是它雖然具有GUI模塊(即highgui),但是實在是很簡陋,就連一個按鍵都無法直接實現(需要藉助滾動條實現),這一點難以滿足可視化的圖像處理的想法;另一方面,Qt作為一個優秀的圖形庫,在GUI上表現出色,且界面設
  •                                                   
  • 瀏覽器和伺服器之間是通過 HTTP 協議進行連接通訊的。這是一種基於請求和響應模型的協議。瀏覽器通過 URL 向伺服器發起請求,Web 伺服器接收到請求,執行一段程式,然後做出響應,發送相應的html代碼給客戶端。 這就有了一個問題,Web 伺服器執行一段程式,可能幾毫秒就完成,也可能幾分鐘都完不成
  • 1.&按位“與”的計算是把兩個數字分別寫成二進位形式,然後按照每一位進行比較,&計算中,只要有一個是0就算成02.|運算轉換成2進位進行比較,兩個位只要有一個為1,那麼結果就是1,否則就為03.^兩個數轉換為2進位然後比較位,相同則結果為0,不同則結果為1
  • Maven引入    我們都知道,在JDK1.5之前,Java中要進行業務併發時,通常需要有程式員獨立完成代碼實現,當然也有一些開源的框架提供了這些功能,但是這些依然沒有JDK自帶的功能使用起來方便。而當針對高質量Java多線程併發程式設計時,為防止死蹦等現象的出現,比如使用java之前的wait(
  • 在《代碼重構(一):函數重構規則(Swift版)》和《代碼重構(二):類重構規則(Swift版)》中詳細的介紹了函數與類的重構規則。本篇博客延續之前博客的風格,分享一下在Swift語言中是如何對數據進行重構的。對數據重構是很有必要的,因為我們的程式主要是對數據進行處理。如果你的業務邏輯非常複雜,那麼
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...