日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在抛弃 MVP-Clean 后,我自主设计并开源了 Viabus 架构

發布時間:2025/3/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在抛弃 MVP-Clean 后,我自主设计并开源了 Viabus 架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文為博主原創文章,轉載請注明作者和鏈接。更多請繼續關注 KunMinX

前言

前不久剛結束對 20 模塊項目的第 3 輪重構,一路見證了 MVC、MVP、Clean 的優缺點并形成自己的體會。

近期在總結工作經驗的同時,開始寫博客。順便開源了我設計的 ViaBus 架構。

項目地址:Github : KunMinX / android-viabus-architecture

? 歡迎 star 和 fork ~

項目常用架構比對

以下,先對常見的 MVC、MVP、Clean、AAC 架構做個比對。

首先,一張表格展示各架構的類冗余情況:

需求是,寫三個頁面,ListFragment、DetailFragment、PreviewFragment,每個頁面至少用到 3個 Note 業務、3個 User 業務。問:上述架構分別需編寫多少類?

架構涉及類類總數
MVCFragment:3個,Controller:3個,Model:2個8個
MVPFragment:3個,Presenter:3個,Model:3個,Contract:1個10個
CleanFragment:3個,ViewModel:3個,Usecase:18個,Model:3個27個
AACFragment:3個,ViewModel:3個,Model:3個9個

MVC 架構的缺陷

  • View、Controller、Model 相互依賴,造成代碼耦合。
  • 難以分工,難以將 View、Controller、Model 分給不同的人寫。
  • 難以維護,沒有中間件接口做緩沖,難以替換底層的實現。
public class NoteListFragment extends BaseFragment {...public void refreshList() {new Thread(new Runnable() {@Overridepublic void run() {//view 中直接依賴 model。那么 view 須等 model 編寫好才能開工。mNoteList = mDataManager.getNoteList();mHandler.sendMessage(REFRESH_LIST, mNoteList);}}).start();}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg) {case REFRESH_LIST:mAdapter.setList(mNoteList);mAdapter.notifyDataSetChanged();break;default:}}};... }

MVP 架構的特點與局限

  • MVP 架構的特點是 面向接口編程。在 View、Presenter、Model 之間分別用 中間件接口 做銜接,當有新的底層實現時,能夠無縫替換。
  • 此外,MVP 的 View 和 Model 并不產生依賴,因此可以說是對 View 和 Model 做了代碼解耦。
public class NoteListContract {interface INoteListView {void showDialog(String msg);void showTip(String tip);void refreshList(List<NoteBean> beans);}interface INoteListPresenter {void requestNotes(String type);void updateNotes(NoteBean... beans);void deleteNotes(NoteBean... beans);}interface INoteListModel {List<NoteBean> getNoteList();int updateNote(NoteBean bean);int deleteNote(NoteBean bean);} }

但 MVP 架構有其局限性。按我的理解,MVP 設計的初衷是, “讓天下沒有難替換的 View 和 Model” 。該初衷背后所基于的假設是,“上層邏輯穩定,但底層實現更替頻繁” 。在這個假設的引導下,使得三者中, 只有 Presenter 具備獨立意志和決定權,掌管著 UI 邏輯和業務邏輯,而 View 和 Model 只是外接的工具

public class NoteListPresenter implements NoteListContract.INoteListPresenter {private NoteListContract.INoteListModel mDataManager;private NoteListContract.INoteListView mView;@Overridepublic void requestNotes(String type) {Observable.create(new ObservableOnSubscribe<List<NoteBean>>() {@Overridepublic void subscribe(ObservableEmitter<List<NoteBean>> e) throws Exception {List<NoteBean> noteBeans = mDataManager.getNoteList();e.onNext(noteBeans);}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<List<NoteBean>>() {@Overridepublic void accept(List<NoteBean> beans) throws Exception {//presenter 直接干預了 UI 在拿到數據后做什么,使得邏輯上沒有發生解耦。//正常來說,解耦意味著,presenter 的職能邊界僅限返回結果數據,//由 UI 來依據響應碼處理 UI 邏輯。mView.refreshList(beans);}});}... }

然而,這樣的假設多數時候并不實際??梢暬枨笫亲兓喽说?#xff0c;在牽涉到視覺交互時,必然涉及 UI 邏輯的修改,也就是說,View 和 Presenter 的相互牽連,使得 UI 的改動需要 View 和 Presenter 編寫者配合著完成,增加溝通協作成本。

長久來看,二者都難以成長。Presenter 編寫者容易被各種非本職工作拖累,View 的編寫者不會嘗試獨立自主,例如通過多態等模式將 UI 封裝成可適應性的組件,反正 ... 有 Presenter 來各種 if else 嘛。

Clean 架構的特點和不足

為解決 Presenter 職能邊界不明確 的問題,在 Clean 架構中,業務邏輯的職能被轉移到領域層,由 Usecase 專職管理。Presenter 則弱化為 ViewModel ,作為代理數據請求,和銜接數據回調的緩沖區。

Clean 架構的特點是 單向依賴、數據驅動編程。 View -> ViewModel -> Usecase -> Model 。

View 對 ViewModel 的單向依賴,是通過 databinding 特性實現的。ViewModel 只負責代理數據請求,在 Usecase 處理完業務返回結果數據時,結果數據被賦值給可觀察的 databinding 數據,而 View 則依據數據的變化而變化。

public class NoteListViewModel {private ObservableList<NoteBean> mListObservable = new ObservableArrayList<>();private void requestNotes(String type) {if (null == mRequestNotesUsecase) {mRequestNotesUsecase = new ProveListInitUseCase();}mUseCaseHandler.execute(mRequestNotesUsecase, new RequestNotesUsecase.RequestValues(type),new UseCase.UseCaseCallback<RequestNotesUsecase.ResponseValue>() {@Overridepublic void onSuccess(RequestNotesUsecase.ResponseValue response) {//viewModel 的可觀察數據發生變化后,databinding 會自動更新 UI 展示。mListObservable.clear();mListObservable.addAll(response.getNotes());}@Overridepublic void onError() {}});}... }

但 Clean 架構也有不足:粒度太細 。一個 Usecase 受限于請求參數,因而只能處理一類請求。View 請求的數據包含幾種類型,就至少需要準備幾個 Usecase。Usecase 是依據當前 View 對數據的需求量身定制的,因此 Usecase 的復用率極低,項目會因而急劇的增加類和重復代碼。

public class RequestNotesUseCase extends UseCase<RequestNotesUseCase.RequestValues, RequestNotesUseCase.ResponseValue> {private DataManager mDataManager;@Overrideprotected void executeUseCase(final RequestValues values) {List<NoteBean> noteBeans = mDataManager.getNotes();...getUseCaseCallback().onSuccess(new RequestNotesUseCase.ResponseValue(noteBeans));}//每新建一個 usecase 類,都需要手動為其配置 請求參數列表 和 響應參數列表。public static final class RequestValues implements UseCase.RequestValues {private String type;public String getType() {return type;}public void setType(String type) {this.type = type;}}public static final class ResponseValue implements UseCase.ResponseValue {public List<NoteBean> mBeans;public ResponseValue(List<NoteBean> beans) {mBeans = beans;}} }

AAC 架構的特點

AAC 也是數據驅動編程。只不過它不依賴于 MVVM 特性,而是直接在 View 中寫個觀察者回調,以接收結果數據并處理 UI 邏輯。

public class NoteListFragment extends BaseFragment {@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);viewModel.getNote().observe(this, new Observer<NoteBean>() {@Overridepublic void onChanged(@Nullable NoteBean bean) {//update UI}});}... }

你完全可以將其理解為 B/S 架構:從 Web 前端向 Web 后端發送了數據請求,后端在處理完畢后響應結果數據給前端,前端再依據需求處理 UI 邏輯。等于說, AAC 將業務完全壓到了 Model 層。

ViaBus 架構的由來及特點

上一輪重構項目在用 Clean 架構,為此我決定跳過 AAC,基于對移動端數據交互的理解,編寫“消息驅動編程”架構。

由于借助總線來代理數據的請求和響應,因此取名 ViaBus。

不同于以往的架構,ViaBus 明確界定了什么是 UI,什么是業務。

UI 的作用是視覺交互,為此 UI 的職責范圍是請求數據和處理 UI 邏輯 。業務的作用是供應數據,因此 業務的職責范圍是接收請求、處理數據、返回結果數據

UI 不需要知道數據是怎么來的、通過誰來的,它只需向 bus 發送一個請求,如果有業務注冊了該類 “請求處理者”,那么自然有人來處理。業務也無需知道 UI 在拿到數據后會怎么用,它只需向 bus 回傳結果,如果有 UI 注冊了“觀察響應者”,那么自然有人接收,并依據響應碼行事。

這樣,在靜態 bus 的加持下,UI 和業務是完全解耦的,從根本上解決了相互牽連的問題。此外,不同于上述架構的每個 View 都要對應一個 Presenter 或 ViewModel,在 ViaBus 中,一個模塊中的 UI 可以共享多個“業務處理者”實例,使 代碼的復用率提升到100%。

ViaBus 現已在 Github 開源,歡迎 Star & Fork ~

更多訪問

Github : KunMinX / android-viabus-architecture
1分鐘掌握 ViaBus 架構的使用
ViaBus - 年輕人的第一款 Android 架構

總結

以上是生活随笔為你收集整理的在抛弃 MVP-Clean 后,我自主设计并开源了 Viabus 架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。