MVP框架

2017-08-26  本文已影响0人  郑在学_blog
MVP框架图示
  1. 各部分之间的通信,都是双向的。

  2. View 与 Model 不发生联系,都通过 Presenter 传递。

  3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

在Android中使用MVP框架

MVP框架的简单demo

1.实体类(属于Model层)

public class UserBean {
    private String mFirstName;
    private String mLastName;

    public UserBean(String firstName, String lastName) {

        this.mFirstName = firstName;
        this.mLastName = lastName;
    }

    public String getFirstName() {
        return mFirstName;
    }

    public String getLastName() {
        return mLastName;
    }
}
  1. View层接口
public interface IUserView {
    /*
     View层,对ID,FirstName,LastName
     这三个EditText进行读操作
    */
    int getID();
    String getFristName();
    String getLastName();
    /*
      对FirstName,LastName
      进行写操作(根据ID,获得FirstName,LastName,并显示出来)
     */
    void setFirstName(String firstName);
    void setLastName(String lastName);
}

  1. 实现View层接口,在Android中通常是Activity实现的
public class UserActivity extends AppCompatActivity implements
        View.OnClickListener, IUserView {

    private EditText mFirstNameEditText, mLastNameEditText, mIdEditText;
    private Button mSaveButton, mLoadButton;
    private UserPresenter mUserPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user);
        findWidgets();
        //实例化一个 Presenter的对象
        mUserPresenter = new UserPresenter(this);
        mSaveButton.setOnClickListener(this);
        mLoadButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.saveButton:
                mUserPresenter.saveUser(getID(), getFristName(),
                        getLastName());
                break;
            case R.id.loadButton:
                mUserPresenter.loadUser(getID());
                break;
            default:
                break;
        }
    }

    @Override
    public void setFirstName(String firstName) {
        mFirstNameEditText.setText(firstName);
    }

    @Override
    public void setLastName(String lastName) {
        mLastNameEditText.setText(lastName);
    }

    @Override
    public int getID() {
        return Integer.parseInt(mIdEditText.getText().toString());
    }

    @Override
    public String getFristName() {
        return mFirstNameEditText.getText().toString();
    }

    @Override
    public String getLastName() {
        return mLastNameEditText.getText().toString();
    }

    void findWidgets() {
        mFirstNameEditText = (EditText) findViewById(R.id.first_name_edt);
        mLastNameEditText = (EditText) findViewById(R.id.last_name_edt);
        mIdEditText = (EditText) findViewById(R.id.id_edt);

        mSaveButton = (Button) findViewById(R.id.saveButton);
        mLoadButton = (Button) findViewById(R.id.loadButton);
    }
}

附:
实例化一个Present的对象,传入Activity。 Activity通过接口与Presenter进行互动, 这样可以降低耦合

  1. Present层,作为V层和M层的联系。
public class UserPresenter {
    private IUserView mUserView;   //视图View层的接口实例
    private IUserModel mUserModel; //模型Model层的接口实例

    public UserPresenter(IUserView view) {
        mUserView = view;
        mUserModel = new UserModel();
    }

    /*
    保存view层看到的数据的处理逻辑放在Presenter 里面实现
    但实际是调用模型Model的接口,把操作交付给Model层去处理实现。
    */
    public void saveUser(int id, String firstName, String lastName) {
        mUserModel.setID(id);
        mUserModel.setFirstName(firstName);
        mUserModel.setLastName(lastName);
    }

    /**
     * 在Presenter中调用Model处理完数据后
     * 通过IUserView更新View显示的信息
     * @param id
     */
    public void loadUser(int id) {
        UserBean user = mUserModel.load(id);
        mUserView.setFirstName(user.getFirstName());
        mUserView.setLastName(user.getLastName());
    }
}

附:
1.Present层都是通过接口进行互动,可以降低耦合
2.Present层的构造方法通常传入View接口对象,构造Model接口对象。
3.保存view层看到的数据的处理逻辑放在Presenter 里面实现,但实际是调用模型Model的接口,把操作交付给Model层去处理实现。体现了Present层只是V层和M层的联系。

5.Model接口层

public interface IUserModel {
    /*
    在Model层对三个字段进行写操作
     */
    void setID(int id);
    void setFirstName(String firstName);
    void setLastName(String lastName);

    /*
    在Model层根据ID读取数据:FirstName,LastName
    返回一个UserBean 对象实体
    */
    UserBean load(int id);
}

6.实现Model接口层

public class UserModel implements IUserModel{

    @Override
    public void setID(int id) {

    }

    @Override
    public void setFirstName(String firstName) {

    }

    @Override
    public void setLastName(String lastName) {

    }

    @Override
    public UserBean load(int id) {
        return null;
    }
}


附:
负责数据的存储、检索、操作,具体逻辑没有详细列出。

MVP模式的优点:
1.MVP模式会解除View与Model的耦合,有效的降低View的复杂性。同时又带来了良好的可扩展性、可测试性,保证系统的整洁性和灵活性。
在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。
MVP模式的缺点:
1.每一个View都需要连接一个Present,容易造成类数量爆炸,代码复杂度和学习成本高,在某些场景下presenter的复用会产生接口冗余。实际工作中没法抽象使得presenter重用。有时候业务简单就直接一个Activity搞定了。

上一篇下一篇

猜你喜欢

热点阅读