簡體   English   中英

Android MVP模式包結構

[英]Android MVP pattern package structure

我在android中看到了關於MVP模式的各種精彩教程,但作者們似乎都在包裝上有不同的練習。

我看到的第一個教程按功能進行了打包。 如,“登錄”,“加入”,“UI”包。

UI包只有活動,“Login”包具有演示者和具體演示者的接口,並且該包包含一個子包“Model”,其中包含有關登錄模型的所有內容(與服務器的通信)。 “Join”包與“Login”包具有相同的組成。

但是我看到的另一個按場景打包,例如“加入”,“登錄”。

“Join”包中包含一個活動,以及三個名為“Model”,“View”,“Presenter”的子包。

什么是最佳做法? 有沒有處理這個問題的文章?

應用程序應根據features而不是通用功能進行打包。

我發現人們制作活動,片段,適配器等。 一組中的共同目的包,但這是不好的做法

大多數開發人員將它們分組為這樣,因為他們這樣做是為了保持他們所使用的所有應用程序的相同包結構 但這是非常錯誤的決定因為當它們被分組時,因為它們共享相同的父類而總是很難找到類!

我們應該根據父類對這些類進行分組,但只有在我們制作一些API但是如果我們為我們的客戶制作定制產品時,這是非常糟糕的做法。

像大多數開發人員放入活動包的所有活動一樣,因為所有活動類都擴展了Activity類。這是有意義的,這只是與活動相關的包,但很難通過這些包。

假設我們有一個OrderListActivity類,我們從服務器獲取訂單列表,然后在一個OrderListFragment類中顯示它,顯然我們需要OrderListAdapter來顯示訂單列表。 因此,當客戶在訂單列表屏幕上要求進行某些修改或任何他想要的功能時,我們必須轉到許多包以滿足客戶需求。 就像我們必須轉到活動包並在OrderListActivity中修改一些東西然后轉到OrderListFragment然后轉到OrderListAdapter然后轉到OrderListViewHolder等等!所以這變得太難了我們可能會在修改過程中產生問題!

所以我們應該將要改變/修改的類組合在一起。

這是最佳實踐,因此我們應該將所有負責OrderListing功能的類分組到一個包中,我們稱之為orderdlist包。

請檢查我的這篇媒體帖子我已經解釋了包裝結構: -

https://medium.com/@kailash09dabhi/mvp-with-better-naming-of-implementation-classes-dry-principle-e8b6130bbd02

好的做法是按功能(有時被視為模塊)和圖層而不是按角色來分隔內容。 原因:類/接口名稱已經告知,例如LoginView,LoginPresenter,LoginFragment,LoginActivity等。

我只是在這里重新發布我的答案

我經常將業務邏輯代碼放在模型層中 (不要與數據庫中的模型混淆)。 我經常將其重命名為XManager以避免混淆(例如ProductManagerMediaManager ......),因此演示者類僅用於保持工作流程。

經驗法則是沒有或至少限制在演示者類中導入android包 這個最佳實踐支持您更輕松地測試presenter類,因為presenter現在只是一個普通的java類,所以我們不需要android框架來測試這些東西。

例如,這是我的mvp工作流程。

視圖類 :這是一個存儲所有視圖的位置,例如按鈕,textview ...並且您在此圖層上設置這些視圖組件的所有偵聽器。 此視圖上,您​​還可以在以后為演示者實現定義一個Listener類。 您的視圖組件將調用此偵聽器類上的方法。

class ViewImpl implements View {
   Button playButton;
   ViewListener listener;

   public ViewImpl(ViewListener listener) {
     // find all view

     this.listener = listener;

     playButton.setOnClickListener(new View.OnClickListener() {
       listener.playSong();
     });
   }

   public interface ViewListener {
     playSong();
   }
}

Presenter類:這是您在里面存儲視圖和模型以便稍后調用的地方。 另外,presenter類將實現上面定義的ViewListener接口。 演示者的要點是控制邏輯工作流程。

class PresenterImpl extends Presenter implements ViewListener {
    private View view;
    private MediaManager mediaManager;

    public PresenterImpl(View, MediaManager manager) {
       this.view = view;
       this.manager = manager;
    }

    @Override
    public void playSong() {
       mediaManager.playMedia();
    }
}

Manager類:這是核心業務邏輯代碼。 也許一位主持人會有很多經理(取決於視圖的復雜程度)。 通常我們通過一些注入框架(如Dagger獲取Context類。

Class MediaManagerImpl extends MediaManager {
   // using Dagger for injection context if you want
   @Inject
   private Context context;
   private MediaPlayer mediaPlayer;

   // dagger solution
   public MediaPlayerManagerImpl() {
     this.mediaPlayer = new MediaPlayer(context);
   }

   // no dagger solution
   public MediaPlayerManagerImpl(Context context) {
     this.context = context;
     this.mediaPlayer = new MediaPlayer(context);
   }

   public void playMedia() {
     mediaPlayer.play();
   }

   public void stopMedia() {
      mediaPlayer.stop();
   }
}

最后:將這些內容放在“活動”,“片段”中......這是您初始化視圖,管理器並將所有內容分配給演示者的位置。

public class MyActivity extends Activity {

   Presenter presenter;

   @Override
   public void onCreate() {
      super.onCreate();

      IView view = new ViewImpl();
      MediaManager manager = new   MediaManagerImpl(this.getApplicationContext());
      // or this. if you use Dagger
      MediaManager manager = new   MediaManagerImpl();
      presenter = new PresenterImpl(view, manager);
   }   

   @Override
   public void onStop() {
     super.onStop();
     presenter.onStop();
   }
}

您會看到每個演示者,模型,視圖都由一個界面包裝。 這些組件將通過接口調用。 此設計將使您的代碼更加健壯,以后更容易修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM