浅谈MVP模式

之前有看过MVP的介绍,也没有实际的用过,今天学弟问我有没有用过MVP,就一起来研究研究。
提到MVP,就不得不说说MVC模式,MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。

  • Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View(视图) - 视图代表模型包含的数据的可视化。
  • Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

MVC 分层有助于管理复杂的应用程序,因为我们可以在一个时间内专门关注一个方面。例如,我们可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。

MVC

由结构图我们可以看到,在MVC模式中,虽然Controller控制着数据流向以及视图,但是View和Model之间也存在直接交互,在Android的开发中,我们通常都会把逻辑代码卸载Activity中,这样就会是的Activity逐渐变得臃肿不堪,为了解决这样的问题,就引入了新的模式,即MVP。

MVP

在MVP中,Prensenter(表示器)取代了MVC中的Controller,同时Activity的职责发生了变化,由原来的C变成了 V,不再管控制层的问题,只管如何去显示。控制层的角色就由我们的新人 Presenter来担当,这种架构就解决了Activity过度耦合控制层和视图层的问题。还有一点就是Presenter与View之间的交互是通过接口的且V和M不可以直接进行交互。

由于身边环境的限制,我将以JAVA中的GUI开发演示MVP的开发方式,毕竟我们主要是阐述MVP的思想。我们一一个登录作为例子,将我们的包及代码结构搭建起来。

包结构如下:
包结构

我们先来看一下Model层中的接口和实现类:

package com.jianggujin.mvp.model;

public interface LoginModel
{
   void login(String name, String pass, OnLoginFinishedListener listener);

   public interface OnLoginFinishedListener
   {
      void onNameError();

      void onPassError();

      void onSuccess();
   }
}
package com.jianggujin.mvp.model.impl;

import com.jianggujin.mvp.model.LoginModel;

public class LoginModelImpl implements LoginModel
{

   @Override
   public void login(String name, String pass, OnLoginFinishedListener listener)
   {
      if (isEmpty(name))
      {
         listener.onNameError();
         return;
      }
      if (isEmpty(pass))
      {
         listener.onPassError();
         return;
      }
      listener.onSuccess();
   }

   private boolean isEmpty(String msg)
   {
      return msg == null || msg.length() == 0;
   }

}

在用户登录的模型中,我们使用login方法来模拟用户名密码的校验。

接下来,我们来看View层中的接口和实现类。

package com.jianggujin.mvp.view;

public interface LoginView
{
   void setNameError();

   void setPassError();

   void setSuccess();
}
package com.jianggujin.mvp.view.impl;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import com.jianggujin.mvp.presenter.LoginPresenter;
import com.jianggujin.mvp.presenter.impl.LoginPresenterImpl;
import com.jianggujin.mvp.view.LoginView;

@SuppressWarnings("serial")
public class LoginViewImpl extends JFrame implements LoginView
{
   private LoginPresenter presenter;

   private JTextField userNameText;
   private JPasswordField passwordText;
   private JButton loginButton;

   public LoginViewImpl()
   {
      super("登录");
      presenter = new LoginPresenterImpl(this);
      userNameText = new JTextField(20);
      passwordText = new JPasswordField(20);
      loginButton = new JButton("登录");
      loginButton.addActionListener(new ActionListener()
      {
         @Override
         public void actionPerformed(ActionEvent e)
         {
            presenter.validateCredentials(userNameText.getText(), new String(passwordText.getPassword()));
         }
      });
      Box root = Box.createVerticalBox();
      root.add(userNameText);
      root.add(passwordText);
      root.add(loginButton);
      add(root);

      this.pack();
      this.setLocationRelativeTo(null);
      this.setDefaultCloseOperation(EXIT_ON_CLOSE);
   }

   @Override
   public void setNameError()
   {
      JOptionPane.showMessageDialog(this, "用户名错误", "错误", JOptionPane.ERROR_MESSAGE);
   }

   @Override
   public void setPassError()
   {
      JOptionPane.showMessageDialog(this, "密码错误", "错误", JOptionPane.ERROR_MESSAGE);
   }

   @Override
   public void setSuccess()
   {
      JOptionPane.showMessageDialog(this, "登录成功", "提示", JOptionPane.INFORMATION_MESSAGE);
   }

}

登录的视图仅负责页面的展示,当存在与用户交互的时候,将交由LoginPresenter处理。

最后,我们来看Presenter层中的接口和实现类。

package com.jianggujin.mvp.presenter;

public interface LoginPresenter
{
   void validateCredentials(String name, String pass);
}
package com.jianggujin.mvp.presenter.impl;

import com.jianggujin.mvp.model.LoginModel;
import com.jianggujin.mvp.model.LoginModel.OnLoginFinishedListener;
import com.jianggujin.mvp.model.impl.LoginModelImpl;
import com.jianggujin.mvp.presenter.LoginPresenter;
import com.jianggujin.mvp.view.LoginView;

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener
{
   private LoginView loginView;
   private LoginModel loginModel;

   public LoginPresenterImpl(LoginView loginView)
   {
      this.loginView = loginView;
      loginModel = new LoginModelImpl();
   }

   @Override
   public void validateCredentials(String name, String pass)
   {
      loginModel.login(name, pass, this);
   }

   @Override
   public void onNameError()
   {
      loginView.setNameError();
   }

   @Override
   public void onPassError()
   {
      loginView.setPassError();
   }

   @Override
   public void onSuccess()
   {
      loginView.setSuccess();
   }

}

Presenter扮演着View和Model的中间层的角色。获取model层的数据之后构建view层;也可以收到view层UI上的反馈命令后分发处理逻辑,交给model层做业务操作。它也可以决定View层的各种操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值