android MVP 开发模式

来源:互联网 发布:数据挖掘目的 编辑:程序博客网 时间:2024/05/17 02:51

android MVP 开发模式的理解

       在进入MVP介绍前。我们先来看一下一直沿用的MVC的开发的模式。


       明人一看上面的结构图就知道MVC中是允许Model 和 View  进行交互的。

每种模式都有利与弊,不能说那种模式好与不好。为了“高内聚,低耦合”的思想。个人觉得MVP更能体现之特性。

下面让我们来看看MVP的结构图:


   View对应于activity,负责View的绘制以及用户的交互,理应做到View是最薄的一层,利于UI重新设计与变更。     Model 数据源与实体模型。比如,保存到本地的数据。数据库的数据。网络请求回来的数据。     Presenter 负责View与Model的交互。起到一个中间的角色。说白了就是个控制器。由它来控UI的数据来源和UI显示。

  • 如果理解这三个概念。接下来就说说代码结构吧。

代码分块。这并不是MVP的主旨。可以根据个人爱好来分。最重要的是我们在写代码时,如何运用MVP的思维。做到代码清淅明了,维护性高。逻辑简单明了。

接下来看一个简单的例子。如


/** * Created by cc on 16/4/13. */public interface ILoginView {    String getPhone();    String getPassWord();    void setPhone(String phone);    void setPassWroid(String passWroid);    void startIndexActivity();    void startForgetActivity();    Context getContext();    void promptToastMessge(String msg);    void showProgressBar(String msg);    void setProgressBarMessage(String msg);    void hideProgressBar();}

/** * Created by cc on 16/4/13. */public interface ILoginMode {    void onSuccess(Object object);    void onFail(Object object);}
/** * Created by cc on 16/4/13. */public class LoginService {    public LoginService(final ILoginMode iLoginMode) {        //这里模拟网络请求。按道理来说。这里不该出现os包的代码。这里只为了测试。        // 建设 model层。放在异步线程执行。可以试一下        //Rx(rxjava或rxandroid) 与 Retrogit        //Rx(rxjava或rxandroid) 可以简单理解为"异步"        //Retrogit网络请求       new Handler().postDelayed(new Runnable() {           @Override           public void run() {               //模拟加载数据               if (new Random().nextBoolean()){                   iLoginMode.onSuccess("请求成功");                   return;               }               iLoginMode.onFail("请求失败");           }       },3000);    }}

/** * Created by cc on 16/4/13. */public class LoginPresenter {    private ILoginView mILoginView;    public LoginPresenter(ILoginView iLoginView) {        mILoginView = iLoginView;    }    public void onCreate() {        LocalLoginPhone localLoginPhone = new LocalLoginPhone();        String phone = localLoginPhone.getLoginPhone(mILoginView.getContext());        mILoginView.setPhone(phone);    }    public void deletePhoneClick() {        mILoginView.setPhone("");    }    public void deletePassWordClick() {        mILoginView.setPassWroid("");    }    public void forgetPassWordClick() {        mILoginView.startForgetActivity();    }    public void LoginClick() {        String phone = mILoginView.getPhone();        if (TextUtils.isEmpty(phone)) {            mILoginView.promptToastMessge("填写信息有误");            return;        }        String possWord = mILoginView.getPassWord();        if (TextUtils.isEmpty(possWord)) {            mILoginView.promptToastMessge("填写信息有误");            return;        }        mILoginView.showProgressBar("正在加载");        LoginService loginService = new LoginService(new ILoginMode() {            @Override            public void onSuccess(Object object) {                mILoginView.setProgressBarMessage(object.toString());                mILoginView.hideProgressBar();                mILoginView.startIndexActivity();            }            @Override            public void onFail(Object object) {                mILoginView.setProgressBarMessage(object.toString());                mILoginView.hideProgressBar();                mILoginView.promptToastMessge("提交失败");            }        });    }}

/** * Created by cc on 16/4/13. */public class LogInActivity extends BaseActivity implements ILoginView {    private EditText login_et_phone, login_et_password;    private Button login_btn_delete_phone, login_btn_delete_password, login_btn_login, login_btn_forget_password;    private LoginPresenter mLoginPresenter;    private LittleDialog mDialog;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.act_login);        initView();        mLoginPresenter = new LoginPresenter(this);        mLoginPresenter.onCreate();    }    private void initView() {        login_et_phone = (EditText) findViewById(R.id.login_et_phone);        login_et_password = (EditText) findViewById(R.id.login_et_password);        login_btn_delete_phone = (Button) findViewById(R.id.login_btn_delete_phone);        login_btn_delete_password = (Button) findViewById(R.id.login_btn_delete_password);        login_btn_login = (Button) findViewById(R.id.login_btn_login);        login_btn_forget_password = (Button) findViewById(R.id.login_btn_forget_password);        login_btn_delete_phone.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mLoginPresenter.deletePhoneClick();            }        });        login_btn_delete_password.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mLoginPresenter.deletePassWordClick();            }        });        login_btn_login.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mLoginPresenter.LoginClick();            }        });        login_btn_forget_password.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mLoginPresenter.forgetPassWordClick();            }        });    }    @Override    public String getPhone() {        return login_et_phone.getText().toString().trim();    }    @Override    public String getPassWord() {        return login_et_password.getText().toString().trim();    }    @Override    public void setPhone(String phone) {        login_et_phone.setText(phone);    }    @Override    public void setPassWroid(String passWroid) {        login_et_password.setText(passWroid);    }    @Override    public void startIndexActivity() {        UIHelper.startActivity(this, IndexActivity.class, null);    }    @Override    public void startForgetActivity() {    }    @Override    public Context getContext() {        return this;    }    @Override    public void promptToastMessge(String msg) {        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();    }    @Override    public void showProgressBar(String msg) {        mDialog = new LittleDialog(this, msg);        mDialog.show();    }    @Override    public void setProgressBarMessage(String msg) {        if (null != mDialog)            mDialog.setMessage(msg);    }    @Override    public void hideProgressBar() {        if (null != mDialog)            mDialog.dismiss();    }}

/** * UI操作辅助类 * @author alafighting 2016-0 */public class UIHelper {    /**     * 界面跳转     * @param context     * @param activity     * @param bundle     */    public static void startActivity(Context context, Class<? extends Activity> activity, Bundle  bundle) {        if (context == null) {            throw new NullPointerException("context不能为空");        }        Intent intent = new Intent(context, activity);        if (null !=bundle){            intent.putExtras(bundle);        }        context.startActivity(intent);    }    /**     * 打开主界面     * @param context     */    public static void startMain(Context context) {        startActivity(context, IndexActivity.class,null);    }}

/** * Created by cc on 16/4/13. */public class BaseActivity extends AppCompatActivity {    public Context getContext() {        return super.getApplicationContext();    }    public Activity getActivity() {        return this;    }    public <T extends android.support.v4.app.Fragment> T findSupportFragment(Class<T> fragmentClass) {        android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();        android.support.v4.app.Fragment fragment = fragmentManager.findFragmentByTag(fragmentClass.getName());        return (T) fragment;    }    public <T extends android.support.v4.app.Fragment> T newSupportFragment(Class<T> fragmentClass, Bundle args) {        android.support.v4.app.Fragment fragment = android.support.v4.app.Fragment.instantiate(getContext(), fragmentClass.getName(), args);        fragment.setArguments(args);        return (T) fragment;    }}

上面的例子是不是看起来很明了。关键问题,大家看到这代码后,会认为这只是把逻辑代码模块的东西放到一另一个类而已。如果你这么理解。说明你对写代码的一个整体认识观不是很有艺术。人人都说写代码是一门艺术。

上面的代码结构还是有好处的。如,当测试跟你说这接口请求出错了。出bug了。这时平常我们会去找到这个接口在那个activity里调用。在那一行代码里。聪明的人可能不会这么干。或许习惯自已写测试用例时,只需调用LoginService实现ILoginModel接口就好了,就可以知道自已有没有搞错了。是不是很 66666

最后说一个mvp 的优点

MVP的优点:

模型与视图完全分离,我们可以修改视图而不影响模型

可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部

我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非    常的有用,因为视图的变化总是比模型的变化频繁。

如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单    元测试)


说明。上面有一两张图是截网上的。如果有侵权,请及时联系我删除,谢谢。

在此感谢以上几个人。老八,壳,替补,roy,朽木,在我理解MVP 过程中。他们给予我解答



0 0
原创粉丝点击