MVP框架

作者: 郑在学_blog | 来源:发表于2017-08-26 00:16 被阅读0次
    MVP框架图示
    1. 各部分之间的通信,都是双向的。

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

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

    在Android中使用MVP框架

    • View 对应于Activity,负责View的绘制以及与用户交互

    • Model 依然是业务逻辑和实体模型

    • Presenter 负责完成View于Model间的交互

    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搞定了。

    相关文章

      网友评论

          本文标题:MVP框架

          本文链接:https://www.haomeiwen.com/subject/zjgpdxtx.html