Android MVP模式包结构

Android MVP pattern package structure

我在 android 看到了各种关于 MVP 模式的很棒的教程,但是作者似乎在打包方面都有不同的做法。

看到的第一个教程是按功能打包的。例如,"Login"、"Join"、"UI" 包。

UI包只有activity,"Login"包有presenter和concrete presenter的接口,这个包包含一个子包"Model",包含关于登录模型(与服务器通信)。 "Join" 包与 "Login" 包的组成相同。

但是我看到的另一个是分场景打包的,比如"Join","Login"。

"Join" 包包含一个 activity 和三个名为 "Model"、"View"、"Presenter" 的子包。

最佳做法是什么?有没有处理这个问题的文章?

最好的做法是按功能(有时被视为模块)和层而不是按它们的作用来分离东西。原因:class/interface名称已经说明,例如LoginView、LoginPresenter、LoginFragment、LoginActivity等

App should have package according to features not by the common functionality.

我发现人们制作 activity、片段、适配器等。 一组通用目的包,但这是不好的做法

大多数开发人员都这样分组,因为他们这样做是为了让他们开发的所有应用程序保持相同的包结构。但这是一个非常错误的决定,因为当它们被分组时总是很难找到 classes 只是因为它们共享相同的父级 classes!

We should group the classes according to parent classes but only if we are making some API but if we are making a custom product for our client then it is very bad practice.!

像大多数开发人员放在 activity 包中的所有活动一样,因为所有 activity classes 扩展 Activity class.That 是有意义的,这只是 activity 相关包,但很难通过这些包。

假设我们有一个 OrderListActivity class,我们从服务器获取订单列表,然后将其显示在一个 OrderListFragment class 中,显然为此我们需要 OrderListAdapter 来显示订单清单。因此,当客户在订单列表屏幕上要求进行一些修改或他想要的任何功能时,我们必须转到许多包以满足客户的需求。就像我们必须转到 activity 打包并修改 OrderListActivity 中的某些内容,然后转到 OrderListFragment,然后是 OrderListAdapter,然后是 OrderListViewHolder,等等!所以这变得太难了,我们可能会在过程中产生问题修改!

so we should group together the classes which are getting changed/modify together.

这是最佳实践,因此我们应该将所有负责 OrderListing 功能的 class 人员分组到一个包中,我们称之为 orderdlist 包。

请检查我的这个媒体post我也已经解释了包结构:--

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

我只是重新发布我的答案

我经常将业务逻辑代码放在模型层(不要与数据库中的模型混淆)。我经常重命名为 XManager 以避免混淆(例如 ProductManagerMediaManager ...),因此演示者 class 仅用于保持工作流程。

经验法则是在演示者 class 中没有或至少限制 导入 android 包 。此最佳实践支持您更轻松地测试 Presenter class,因为 Presenter 现在只是一个普通的 java class,因此我们不需要 android 框架来测试这些东西。

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

视图class:这是一个你存储所有视图的地方,例如按钮,文本视图......并且你为这些视图组件设置所有监听器层。同样在此视图上,您​​稍后为演示者定义一个监听器 class。您的视图组件将调用此侦听器上的方法 class.

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 class: 这是你在里面存放视图和模型的地方,供以后调用。此外,presenter class 将实现上面定义的 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 class: 下面是核心业务逻辑代码。也许一个演示者将有多个经理(取决于视图的复杂程度)。通常我们通过一些注入框架如Dagger.

得到Contextclass
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();
   }
}

最后: 将这些东西放在 Activities、Fragments 中……这是初始化视图、管理器并将它们全部分配给演示者的地方。

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();
   }
}

你看到每个演示者、模型、视图都被一个接口包裹着。这些组件将通过接口调用。这种设计将使您的代码更健壮,更易于以后修改。