我在android中看到了各种关于MVP模式的精彩教程,但作者们在包装上似乎都有不同的做法。
我看到的第一个教程按功能进行了打包。例如,"登录","加入"," UI"包。
UI包只有活动,"登录" package具有演示者和具体演示者的接口,这个包包含一个子包" Model"其中包含有关登录模型的所有信息(与服务器通信)。 "加入"包的组成与"登录"包。
但我看到的另一个按场景打包,例如"加入","登录"。
"加入" package包含一个活动,以及三个名为" Model"," View"," Presenter"的子包。
最佳做法是什么?有没有处理这个问题的文章?
答案 0 :(得分:15)
应用程序应该根据
features
而不是普通的包 功能。
我发现人们制作活动,片段,适配器等。 一组中的共同目的包,但这是不良做法!
大多数开发人员将它们归类为这样,因为他们这样做是为了为他们所使用的所有应用程序保留相同的包结构。但这是非常错误的决定因为只有因为他们共享相同的父类才能在分组时总是很难找到类!
我们应该根据父类对类进行分组,但仅限于 我们正在制作一些API,但如果我们为我们制作定制产品 客户然后这是非常糟糕的做法。!
与大多数开发人员放入活动包的所有活动一样,因为所有活动类都扩展了Activity类。这是有意义的,这只是与活动相关的包,但很难通过这些包。
假设我们有一个OrderListActivity类,我们从服务器获取订单列表,然后在一个OrderListFragment类中显示它,显然我们需要OrderListAdapter来显示订单列表。因此,当客户在订单列表屏幕上要求进行某些修改或任何他想要的功能时,我们必须转到许多包以满足客户需求。就像我们必须转到活动包并在OrderListActivity中修改一些东西然后转到OrderListFragment然后转到OrderListAdapter然后转到OrderListViewHolder等等!这样就变得太难了,我们可能会在修改过程中产生问题!
所以我们应该将正在获得的类组合在一起 一起改变/修改。
这是最好的做法,因此我们应该将所有负责OrderListing功能的类分组到一个包中,我们称之为orderdlist包。
请检查我的这篇媒体帖子我已经解释了包装结构: -
答案 1 :(得分:4)
好的做法是按功能(有时被视为模块)和图层而不是按角色分隔内容。原因:类/接口名称已经告知,例如LoginView,LoginPresenter,LoginFragment,LoginActivity等。
答案 2 :(得分:4)
我只是重新发布我的回答here
我经常将业务逻辑代码放在模型层中(不要与数据库中的模型混淆)。我经常重命名为XManager
以避免混淆(例如ProductManager
,MediaManager
...),因此演示者类仅用于保持工作流程。
经验法则规则中没有或至少限制导入android包。这个最佳实践支持您更轻松地测试presenter类,因为presenter现在只是一个简单的java类,所以我们不需要android框架来测试这些东西。
例如,这是我的mvp工作流程。
查看类:这是一个存储所有视图的地方,例如button,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();
}
}
经理类:这是核心业务逻辑代码。也许一位主持人会有很多经理(取决于视图的复杂程度)。通常我们通过Context
等注入框架获得Dagger
类。
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();
}
}
您会看到每个演示者,模型,视图都由一个界面包装。这些组件将通过接口调用。这种设计将使您的代码更加健壮,以后更容易修改。