一篇使用Clean Architecture(整潔架構)模式開發Android的詳細指南

該文章為翻譯文章
文章出處: https://medium.com/@dmilicic/a-detailed-guide-on-developing-android-apps-using-the-clean-architecture-pattern-d38d71e94029

Ever since I started developing Android apps there was this feeling that it could be done better. I’ve seen a lot of bad software design decisions during my career, some of which were my own?—?and Android complexity mixed with bad software design is a recipe for disaster. But it is important to learn from your mistakes and keep improving. After a lot of searching for a better way to develop apps I encountered the Clean Architecture. After applying it to Android, with some refinement and inspiration from similar projects, I decided that this approach is practical enough and worth sharing.

自從我開始開發安卓后我就有一種它能變得更好的感覺。我曾經在我的職業生涯中遇到過很多糟糕的軟件設計,有一些是我自己的項目--Android的復雜性與糟糕的軟件設計的結合是導致災難的訣竅。但是從中學習到自身的錯誤并且不斷改善是非常重要的。在經過大量搜索尋找適合開發APP的方法后,我邂逅了Clean Architecture。在把它應用到安卓上后,通過相似項目的改進和靈感,我認為這種方法實用并且值得分享。

The goal of this article is to provide a step-by-step guide for developing Android apps in a Clean way. This whole approach is how I’ve recently been building my apps for clients with great success.

這篇文章的目的是通過提供一步步的指導來進行簡潔的安卓項目開發。這整個方法建立在我最近開發客戶端應用上取得巨大成功的基礎上。

What is Clean Architecture?

什么是整潔架構

I will not go into too much detail here as there are articles that explain it much better than I can. But the next paragraph provides the crux of what you need to know to understand Clean.

我不會在這塊深入太多的細節因為有太多相關的文章闡述的比我好。但是下一段是你需要理解整潔的關鍵點。

Generally in Clean, code is separated into layers in an onion shape with one dependency rule: The inner layers should not know anything about the outer layers. Meaning that the dependencies should point inwards.

通常的整潔,是指代碼遵循一個準則分成類似洋蔥裝的層級:內部層級不需要知道外部層級的任何東西。這意味著依賴關系應該指向內部

This is the previous paragraph visualized:

這是先前段落的示意圖
image.png

Clean Architecture, as mentioned in the provided articles, makes your code:
· Independent of Frameworks
· Testable.
· Independent of UI.
· Independent of Database.
· Independent of any external agency.

整潔架構,就像提及的文章所描述的一樣,使你的代碼:

· 獨立架構
· 可測試
· 獨立UI
· 獨立數據庫
· 獨立于任何外部結構

I will hopefully make you understand how these points are achieved with examples below. For a more detailed explanation of Clean I really recommend this article and this video.

我非常希望你可以通過下面的例子來讓你理解這些觀點是如何實現的。更多關于整潔的細節闡述我真心推薦這篇文章和這個視頻

What this means for Android

這對于安卓來說意味著什么

Generally, your app can have an arbitrary amount of layers but unless you have Enterprise wide business logic that you have to apply in every Android app, you will most often have 3 layers:
· Outer: Implementation layer
· Middle: Interface adapter layer
· Inner: Business logic layer

通常,你的app可以擁有任意數量的層級,但是除非你需要在你每個安卓App中實現企業級別的業務邏輯,大多數情況下你會分三個層級:

· 外層: 執行層
· 中層: 接口適配器層
· 內層: 業務邏輯層

The implementation layer is where everything framework specific happens. Framework specific code includes every line of code that is not solving the problem you set to solve, this includes all Android stuff like creating activities and fragments, sending intents, and other framework code like networking code and databases.

執行層是所有具體架構實現的地方。具體架構代碼包括你設置解決但無法解決的每一行代碼,這其中包括所有安卓內容如創建活動和片段、發送意圖和其他的框架代碼如網絡代碼和數據庫。

The purpose of the interface adapter layer is to act as a connector between your business logic and framework specific code.

接口適配器層的目的就是扮演一個在你的業務邏輯和具體架構代碼間的連接者。

The most important layer is the business logic layer. This is where you actually solve the problem you want to solve building your app. This layer does not contain any framework specific code and you should be able to run it without an emulator. This way you can have your business logic code that is easy to test, develop and maintain. That is the main benefit of the Clean Architecture.

最重要的層級是業務邏輯層。這是你實際解決構建應用程序時要解決的問題的地方。這一層級不包含任何具體框架的代碼,并且你應該可以在不借助任何模擬器的情況下運行它。通過這種方式你可以得到易于測試、開發和維護的業務邏輯代碼。這是Clean Architecture整潔架構的主要益處。

Each layer, above the core layer, is also responsible for converting models to lower layer models before the lower layer can use them. An inner layer can not have a reference to model class that belongs to the outer layer. However, the outer layer can use and reference models from the inner layer. Again, this is due to our dependency rule. It does create overhead but it is necessary for making sure code is decoupled between layers.

核心層上方的每個層級還負責在使用較低層時將模型轉變成較低層模型。內層不能引用屬于外層的模型類。但是,外層可以使用和引用內層的模型。同樣,這是由于我們的依賴規則所制定的。它的確會產生開銷但是必須確保代碼在層級之間解耦。

Why is this model conversion necessary? For example, your business logic models might not be appropriate for showing them to the user directly. Perhaps you need to show a combination of multiple business logic models at once. Therefore, I suggest you create a ViewModel class that makes it easier for you to display it to the UI. Then, you use a converter class in the outer layer to convert your business models to the appropriate ViewModel.

為什么需要進行模型轉換?例如,你的業務邏輯模型可能不適合直接展示給用戶。或許你需要一次性展示多種業務邏輯模型的組合。所以,我建議你建立一個ViewModel類來使它更容易地用UI展示。然后,你在外層使用一個轉換類來將你的業務模型轉換為合適的ViewModel

Another example might be the following: Let’s say you get a Cursor object from a ContentProvider in an outer database layer. Then the outer layer would convert it to your inner business model first, and then send it to your business logic layer to be processed.

另一個可能的情況如下:假設你從外部數據庫層級中的ContentProvider中獲取Cursor對象。然后外層會首先將它轉換為內層業務模型,之后將它發送到業務邏輯層進行處理。

I will add more resources to learn from at the bottom of the article. Now that we know about the basic principles of the Clean Architecture, let’s get our hands dirty with some actual code. I will show you how to build an example functionality using Clean in the next section.

我會在下面加入更多的資源以供參考。現在我們知道了一些Clean Architecture整潔架構的基本原理,讓我們用實際的代碼來讓它更加清楚。我會在下一節中像你展示如何使用Clean構建示例功能。

How do I start writing Clean apps?

如何開始創建Clean項目?

I’ve made a boilerplate project that has all of the plumbing written for you. It acts as a Clean starter pack and is designed to be built upon immediately with most common tools included from the start. You are free to download it, modify it and build your apps with it.

我已經創建了一個樣板項目 ,其中包含為你編寫的所有管道。它作為一個Clean的啟動包,旨在立即構建并包含最常用的工具。你可以自由下載、修改并使用它構建你的應用程序。

You can find the starter project here: Android Clean Boilerplate

你可以在這里找到[入門項目]

(https://github.com/dmilicic/Android-Clean-Boilerplate)

Getting started writing a new use case

開始編寫新的用例

This section will explain all the code you need to write to create a use case using the Clean approach on top of the boilerplate provided in the previous section. A use case is just some isolated functionality of the app. A use case may (e.g. on user click) or may not be started by a user.

這一節將會闡述所有你需要寫的代碼來建立一個用例,以使用上一節中提供的樣板文件頂部的Clean方法創建用例。一個用例就是一些應用程序獨立的功能。一個用例(例如用戶點擊)可以或者不可以通過用戶啟動。

First let’s explain the structure and terminology of this approach. This is how I build apps but it is not set in stone and you can organize it differently if you want.

首先讓我們解釋這種方法的一些結構和術語。這就是我構建應用程序的方式,但它不是一成不變的,你可以用你的方式來組織它。

Structure

結構體

The general structure for an Android app looks like this:
· Outer layer packages: UI, Storage, Network, etc.
· Middle layer packages: Presenters, Converters
· Inner layer packages: Interactors, Models, Repositories, Executor

通常安卓應用程序的結構會像下面這樣:

· 外層包: UI, Storage, Network等
· 中層包: Presenters, Converters
· 內層包: Interactors, Models, Repositories, Executor

Outer layer

外層

As already mentioned, this is where the framework details go.

就像已經提及過的那樣,這是運行架構細節的地方。

UI?—?This is where you put all your Activities, Fragments, Adapters and other Android code related to the user interface.

UI-這是你放置你的Activities, Fragments, Adapters和其他安卓代碼來和用戶進行聯系的地方

Storage?—?Database specific code that implements the interface our Interactors use for accessing data and storing data. This includes, for example, ContentProviders or ORM-s such as DBFlow.

Storage-實現Interactors用于訪問數據庫和存儲數據接口的數據庫特定代碼。包括ContentProviders 或ORM-s,如 DBFlow

Network?—?Things like Retrofit go here.

NetWork-類似于Retrofit 運行的地方。

Middle layer

中層

Glue code layer which connects the implementation details with your business logic.

膠水代碼層,用于將實現細節與業務邏輯相關聯。

Presenters?—?Presenters handle events from the UI (e.g. user click) and usually serve as callbacks from inner layers (Interactors).

Presenters-Presenter來處理UI中的事件(如用戶點擊),通常用作內層的回調

Converters?—?Converter objects are responsible for converting inner models to outer models and vice versa.

Coverters-Converter對象負責把內部模型轉換為外部模型,反過來也是這樣。

Inner layer

內層

The core layer contains the most high-level code. All classes here are POJOs. Classes and objects in this layer have no knowledge that they are run in an Android app and can easily be ported to any machine running JVM.

核心層包含最高級的代碼。這里所有的類都是POJO。這一層的類和對象不知道他們運行在安卓應用中并且可以輕松的移植到任何運行JVM的計算機上。

Interactors?—?These are the classes which actually contain your business logic code. These are run in the background and communicate events to the upper layer using callbacks. They are also called UseCases in some projects (probably a better name). It is normal to have a lot of small Interactor classes in your projects that solve specific problems. This conforms to the Single Responsibility Principleand in my opinion is easier on the brain.

Interactors-這些實際上是包含你業務邏輯代碼的類。他們在后臺運行并且通過回調函數向上層傳遞事件。特悶在某些項目中也稱為UseCases(可能是更好的名稱)。在項目組有很多小的Interactor類來解決特定的問題是很正常的。這符合單一責任原則,在我看來這是很容易理解的。

Models?—?These are your business models that you manipulate in your business logic.

模型-這些是你在業務邏輯中操作的業務模型。

Repositories?—?This package only contains interfaces that the database or some other outer layer implements. These interfaces are used by Interactors to access and store data. This is also called a repository pattern.

Repositories-這個包僅存儲數據庫或者外層實現的接口。Interactors使用這些接口來訪問和存儲數據。這也稱作存儲庫模式

Executor****?—?This package contains code for making Interactors run in the background by using a worker thread executor. This package is generally not something you need to change.

Executor-這個包包含使用線程執行程序使Interactors在后臺運行的代碼。這個包通常不是你需要改變的東西。

A simple example

一個簡單的例子

In this example, our use case will be: “Greet the user with a message when the app starts where that message is stored in the database.” This example will showcase how to write the following three packages needed to make the use case work:
· the presentation package
· the storage package
· the domain package

在這個例子中,我們的用例將是:“當應用啟動時,向用戶詢問消息存儲在數據庫中的位置。”這個示例將展示如何編寫使用例工作所需要的三個包:

· 演示包
· 存儲包
· 域包
The first two belong to the outer layer while the last one is the inner/core layer.

頭兩個屬于外層包,最后一個是內層/核心包

Presentation package is responsible for everything related to showing things on the screen?—?it includes the whole MVP stack (it means it also includes both the UI and Presenter packages even though they belong to different layers).

Presentation包負責在屏幕上顯示內容相關的所有內容-它包括整個MVP堆棧(這意味著它還包括UI包和Presenter包,即使他們屬于不同的層)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容

  • 年輕人一到歲數就開始迷茫。畢業季的迷惑、就業時的壓力、物質上的誘惑……什么都想要,卻也什么都得不到。剛剛過完生日的...
    楚慈Human閱讀 280評論 0 0
  • 姓名:仲艷麗 煙臺鴻安集團 日精進打卡第51天 【打卡始于2017.10.11間斷于2017.10.23持續于...
    仲艷麗閱讀 185評論 0 1
  • 從 2007 年至今,你一共購買了多少款iPhone,它們還健在嗎? 從這位網友曬出的照片來看,他確實是一位十足的...
    小書呆子閱讀 190評論 0 0
  • 慢慢的發現自己有一個星期沒有和家里通電話和視屏了,好想回家。 今天,睡醒了,一種感覺就油然而生,想回家,是那種奮不...
    紅茶瓶閱讀 256評論 0 0