繁体   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