純 Flutter 工程的分層架構(gòu)設(shè)計(jì)以及工程化實(shí)踐

一家之言,勿噴偎窘。若有更好方案乌助,歡迎共享。

前言

關(guān)于 Flutter 的教程已經(jīng)有很多了陌知,也有很多優(yōu)秀的開(kāi)源項(xiàng)目他托,這在一定程度上也增加了社區(qū)的活躍度。同時(shí)也有很多商業(yè)項(xiàng)目在實(shí)踐仆葡,不過(guò)多數(shù)是將Flutter工程作為一個(gè)module來(lái)嵌入原生工程赏参。官方有對(duì)應(yīng)的教程來(lái)指導(dǎo)相關(guān)的工程化,網(wǎng)上的教程也很多。

但是一個(gè)純 Flutter 工程的分層架構(gòu)設(shè)計(jì)以及工程化的教程并不是很多把篓。恰巧最近有個(gè)項(xiàng)目需要基于 Flutter 工程來(lái)搭建纫溃,對(duì)分層設(shè)計(jì)以及相應(yīng)的工程化做了一些思考和調(diào)研,此倉(cāng)庫(kù)的目的即在于記錄方案韧掩,與大家分享皇耗。

分層設(shè)計(jì)

分層設(shè)計(jì)和目前成熟的移動(dòng)端的分層設(shè)計(jì)差不多,都是根據(jù)基礎(chǔ)能力和業(yè)務(wù)模塊對(duì) App 進(jìn)行分層以及組件劃分揍很,從而達(dá)到組件化的目的。
例如下圖是一個(gè)很常見(jiàn)的移動(dòng)端分層設(shè)計(jì)万伤。

移動(dòng)端分層.png

將與業(yè)務(wù)無(wú)關(guān)的基礎(chǔ)能力剝離出來(lái)窒悔,沉淀到最底層,上層的業(yè)務(wù)都會(huì)基于這些能力去構(gòu)建敌买;中間劃出一個(gè)業(yè)務(wù)能力層简珠,多數(shù)是一些弱業(yè)務(wù)邏輯的模塊,像分享虹钮、支付這樣的能力聋庵;然后是業(yè)務(wù)模塊,這些基本上就是用戶(hù)可感知的界面以及業(yè)務(wù)邏輯了芙粱;最后是宿主App祭玉。基于這樣的分層設(shè)計(jì)春畔,宿主App一般都是個(gè)殼工程脱货。

針對(duì)這樣的設(shè)計(jì),相應(yīng)的組件間通信方案律姨、工程化方案都已經(jīng)很成熟振峻,而且可選方案也很多。這里不再贅述择份,感興趣的可以自行Google扣孟。

所以我們的Flutter應(yīng)該也是可以按照這樣的分層去設(shè)計(jì),但是由于Flutter開(kāi)發(fā)中可能會(huì)遇到需要原生提供能力的場(chǎng)景荣赶,這樣就會(huì)有一部分能力是基于原生能力封裝的插件凤价,但總的分層設(shè)計(jì)還是類(lèi)似的。例如下圖的分層設(shè)計(jì):

flutter分層.png

工程化實(shí)踐

目前網(wǎng)絡(luò)上關(guān)于這一塊的討論比較少讯壶,如果你有看到相關(guān)的文章料仗,歡迎共享。鑒于組內(nèi)iOS的小伙伴是使用VSCode來(lái)開(kāi)發(fā)的伏蚊,所以工程化實(shí)踐也是基于VSCode來(lái)操作的立轧,不過(guò)這個(gè)應(yīng)該影響不大。

模板工程介紹

我們先了解一下Flutter為我們提供的4中模板工程:App、Module氛改、Plugin帐萎、Package

  1. App

我們一般都是創(chuàng)建一個(gè)App工程胜卤,這個(gè)模板工程會(huì)有android疆导、ios目錄,對(duì)應(yīng)存放的是兩個(gè)平臺(tái)的工程葛躏。

  1. Module

使用這個(gè)模板創(chuàng)建出來(lái)的工程澈段,會(huì)有.android.ios目錄舰攒,從模板的名稱(chēng)可以猜到應(yīng)該是作為Module來(lái)使用的败富,官方對(duì)于這個(gè)模板的應(yīng)用場(chǎng)景是將Flutter作為原生的一個(gè)子Module。這個(gè)模板創(chuàng)建的時(shí)候也會(huì)有main.dart文件摩窃,可以單獨(dú)運(yùn)行在你的設(shè)備上兽叮。

  1. Plugin

如果你需要封裝基于原生能力的插件,就需要用到這個(gè)模板猾愿。

  1. Package

這是一個(gè)純Flutter模塊鹦聪,沒(méi)有androidios目錄蒂秘。

pubspec.yaml 配置介紹

看過(guò)Flutter教程的應(yīng)該都了解泽本,如果我們需要引用一些第三方庫(kù),就可以在這里配置材彪,一般我們配置的都是發(fā)布在 pub.dev 上的開(kāi)源項(xiàng)目观挎。但其實(shí),除了可以直接依賴(lài)pub.dev段化,他還支持本地依賴(lài)嘁捷,git 倉(cāng)庫(kù)依賴(lài)。你可以這樣操作:

dependencies:
  plugin1:
    git:
      url: "git://github.com/flutter/plugin1.git"
  fish_redux:
    path: my_package/fish_redux-0.3.1

另外git依賴(lài)還支持指定branch显熏,指定子目錄等雄嚣。

好了,鋪墊了這么多喘蟆,是時(shí)候介紹我們的工程化方案了缓升。

具體方案

鑒于目前還處于初步實(shí)踐階段,所以并沒(méi)有將各個(gè)組件上傳到git倉(cāng)庫(kù)蕴轨,而是采用基于本地依賴(lài)的方式港谊。因?yàn)楦鱾€(gè)組件可能會(huì)頻繁變動(dòng),就會(huì)不停的切換工程等橙弱。等后期穩(wěn)定后歧寺,可以采用git依賴(lài)的方式燥狰,達(dá)到供多個(gè)App使用的目的。

先來(lái)看一下整個(gè)工程的目錄結(jié)構(gòu)斜筐,如果你有一定的分層設(shè)計(jì)經(jīng)驗(yàn)龙致,應(yīng)該很容易理解這個(gè)目錄結(jié)構(gòu)的設(shè)計(jì)。

目錄結(jié)構(gòu).png

HostApp :殼工程目錄
BusinessModule :業(yè)務(wù)模塊目錄
BusinessLib:業(yè)務(wù)能力目錄顷链,里面還有個(gè)二級(jí)的UI目錄目代,存放一些和業(yè)務(wù)相關(guān)的公共UI組件
CommonLib :基礎(chǔ)能力目錄

按照上面的思路,我們首先需要一個(gè)殼工程嗤练,我們使用VSCode新建一個(gè)App工程榛了,這里放在HostApp目錄下。

接著我們?cè)?code>BusinessModule中新建四個(gè)業(yè)務(wù)模塊工程煞抬,這次我們不再新建App工程忽冻,而是新建Module工程。我這邊新建了module_home此疹、module_usermodule_task遮婶、module_setting四個(gè)工程蝗碎。

同樣,我們?cè)?code>BusinessLib中也新建幾個(gè)工程旗扑,供測(cè)試使用蹦骑,這里新建了lib_accountlib_push臀防、lib_share眠菇,然后在UI目錄中新建了lib_alertlib_banner袱衷、lib_loading捎废。在CommonLib新建lib_databaselib_log致燥、lib_network登疗。其中lib_accountlib_database嫌蚤、lib_networkPackage工程辐益,lib_pushlib_share脱吱、lib_alert智政、lib_bannerlib_loadingModule工程箱蝠,lib_logPlugin工程续捂。大家根據(jù)自己的實(shí)際場(chǎng)景去新建對(duì)應(yīng)的模板工程垦垂。

這樣所有的工程都放在對(duì)應(yīng)的目錄,為了方便管理疾忍,我們新建一個(gè)workspace來(lái)管理所有的工程乔外。具體可以這樣操作:

  1. VSCodeNew Window
  2. Add Folder to Workspace...,選擇我們的根目錄
  3. Save Workspace As...一罩,保存到我們的根目錄

下次可以直接打開(kāi)我們的workspace文件杨幼。

現(xiàn)在打開(kāi)host_app工程的pubspec.yaml做如下配置掀亩,將BusinessModule中的組件引入進(jìn)來(lái)阁苞。

dependencies:
  module_home:
    path: ../../BusinessModule/module_home
  module_user:
    path: ../../BusinessModule/module_user
  module_setting:
    path: ../../BusinessModule/module_setting
  module_task:
    path: ../../BusinessModule/module_task

保存后運(yùn)行flutter pub get

這里有個(gè)小問(wèn)題耕肩,就是使用workspace后汉嗽,在host_app里面去引用module_home內(nèi)定義的頁(yè)面欲逃,沒(méi)有代碼提示,但是手動(dòng)import后饼暑,編譯都正常稳析。不知道是Bug還是我使用的有問(wèn)題。

我們?cè)?code>module_home弓叛、module_user彰居、module_settingmodule_task中各新建一個(gè)頁(yè)面撰筷,HomePage陈惰、UserPageSettingPage毕籽、TaskPage抬闯。

我們?cè)?code>host_app的入口構(gòu)建一個(gè)Tab頁(yè)面,將我們的HomePage关筒、UserPage作為兩個(gè)Tab加載進(jìn)來(lái)溶握。試著運(yùn)行一下,感覺(jué)良好蒸播。

哇哦奈虾,基本的框架已經(jīng)搭建出來(lái)了,雖然后續(xù)需要處理的事情還有很多廉赔,例如組件間的頁(yè)面如何跳轉(zhuǎn)肉微、組件間如何通信,都需要有對(duì)應(yīng)的方案實(shí)現(xiàn)蜡塌。

且等我繼續(xù)調(diào)研實(shí)踐碉纳。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市馏艾,隨后出現(xiàn)的幾起案子劳曹,更是在濱河造成了極大的恐慌奴愉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铁孵,死亡現(xiàn)場(chǎng)離奇詭異锭硼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蜕劝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)檀头,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人岖沛,你說(shuō)我怎么就攤上這事暑始。” “怎么了婴削?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵廊镜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我唉俗,道長(zhǎng)嗤朴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任虫溜,我火速辦了婚禮播赁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吼渡。我一直安慰自己,他們只是感情好乓序,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布寺酪。 她就那樣靜靜地躺著,像睡著了一般替劈。 火紅的嫁衣襯著肌膚如雪寄雀。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天陨献,我揣著相機(jī)與錄音盒犹,去河邊找鬼。 笑死眨业,一個(gè)胖子當(dāng)著我的面吹牛急膀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播龄捡,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼卓嫂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了聘殖?” 一聲冷哼從身側(cè)響起晨雳,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤行瑞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后餐禁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體血久,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年帮非,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氧吐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡喜鼓,死狀恐怖副砍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庄岖,我是刑警寧澤豁翎,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站隅忿,受9級(jí)特大地震影響心剥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜背桐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一优烧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧链峭,春花似錦畦娄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至励饵,卻和暖如春驳癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背役听。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工颓鲜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人典予。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓甜滨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瘤袖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艳吠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容