MVP簡單架構

MVC --> MVP :

將Activity的View和Controller雙重職責分離,Activity單純負責View邏輯,Presenter層處理Model和View層的交互邏輯,Model層處理數據邏輯。

換言之,MVP類似於MVC++,解決分離不徹底的問題。

同時MVP也有一些值得討論的地方:

  • Presenter層與View層是通過接口進行交互,接口粒度控制存在問題。粒度小,接口量過大;粒度大,單一職能性不好。
  • Presenter只是解決了功能分離的問題,複雜業務單個類代碼臃腫問題,仍需要分離多個Presenter - View處理同一個複雜頁面。

瑕不掩瑜,MVP仍然是很好的一套Android前端框架。


文件結構如下:

當然實際項目中不可能這樣分包,這裏只是單純MVP結構劃分的效果。

M、V、P 接口以及具體的實現

Model:這裏只有處理登錄邏輯。持有Presenter

package com.example.mvpdemo.model;

/**
 * Model層 數據邏輯處理
 */
public interface IUserBiz {
    void login(String username, String password);
}
package com.example.mvpdemo.model;

import com.example.mvpdemo.bean.UserBean;
import com.example.mvpdemo.presenter.ILoginPresenter;

/**
 * Model層 具體的數據邏輯實現
 */
public class UserBiz implements IUserBiz {

    private ILoginPresenter mPresenter;

    public UserBiz(ILoginPresenter mPresenter) {
        this.mPresenter = mPresenter;
    }

    @Override
    public void login(String username, String password) {
        // 假設進行了異步登錄
        if ("fengz".equals(username) && "123456".equals(password)) {
            // 持久化用戶信息
            UserBean userBean = new UserBean();
            userBean.setUsername(username);
            userBean.setPassword(password);
            mPresenter.loginSuccess(userBean);
        } else {
            mPresenter.loginFail("假設網絡異常吧!");
        }
    }
}

View:對應登錄邏輯,頁面的不同效果,以及獲取頁面數據。持有Presenter

package com.example.mvpdemo.view;

import com.example.mvpdemo.bean.UserBean;

/**
 * View層 分離UI邏輯
 */
public interface ILoginView {
    
    void toSuccessPage(UserBean user);

    void showErrMessage(String message);
}
/**
 * View層 處理ui邏輯
 */
public class MainActivity extends AppCompatActivity implements ILoginView {

    private EditText mEtUsername;
    private EditText mEtPassword;
    private Button mBtnLogin;

    private LoginPresenter mLoginPrinter = new LoginPresenter(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViews();
    }

    private void findViews() {
        mEtUsername = (EditText) findViewById(R.id.editText2);
        mEtPassword = (EditText) findViewById(R.id.editText);
        mBtnLogin = (Button) findViewById(R.id.button);
        mBtnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mLoginPrinter.login(getUserName(), getPassword());
                showLoading();
            }
        });
    }

    public String getUserName() {
        return mEtUsername.getText().toString();
    }

    public String getPassword() {
        return mEtPassword.getText().toString();
    }

    public void showLoading() {
        Toast.makeText(this, "開始轉菊花", Toast.LENGTH_SHORT).show();
    }

    public void hideLoading() {
        Toast.makeText(this, "結束轉菊花", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void toSuccessPage(UserBean userBean) {
        hideLoading();
        Toast.makeText(this, userBean.getUsername() + "跳轉去主頁面", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showErrMessage(String message) {
        hideLoading();
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}

Presenter:同時持有View和Model,關心交互部分,完全無關邏輯。持有Model和View

package com.example.mvpdemo.presenter;

import com.example.mvpdemo.bean.UserBean;

/**
 * 登錄Presenter接口,處理交互
 */
public interface ILoginPresenter {
    void login(String name,String password);
    void loginSuccess(UserBean user);
    void loginFail(String errMsg);
}
package com.example.mvpdemo.presenter;

import com.example.mvpdemo.bean.UserBean;
import com.example.mvpdemo.model.IUserBiz;
import com.example.mvpdemo.model.UserBiz;
import com.example.mvpdemo.view.ILoginView;

/**
 * Presenter層,同時持有View和Model,只關心交互,不涉及雙方邏輯
 */
public class LoginPresenter implements ILoginPresenter {
    private IUserBiz mUserBiz;
    private ILoginView mLoginView;

    public LoginPresenter(ILoginView mLoginView) {
        this.mLoginView = mLoginView;
        this.mUserBiz = new UserBiz(this);
    }

    @Override
    public void login(String name, String password) {
        mUserBiz.login(name, password);
    }

    @Override
    public void loginSuccess(UserBean user) {
        mLoginView.toSuccessPage(user);
    }

    @Override
    public void loginFail(String errMsg) {
        mLoginView.showErrMessage(errMsg);
    }
}

如上。MVP之外的所有東西都不包含,實現簡單的分層。

Google 官推MVP架構 Presenter層將Model的邏輯也處理在一起,不僅僅作爲中間交互層

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章