标签:public handle 功能 ui线程 prot 而在 ast 可视化 复用
随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责。为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生。
为什么使用MVP模式
在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).
另外,回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。
MVP与MVC的异同
MVC模式与MVP模式都作为用来分离UI层与业务层的一种开发模式被应用了很多年。在我们选择一种开发模式时,首先需要了解一下这种模式的利弊:
无论MVC或是MVP模式都不可避免地存在一个弊端:额外的代码复杂度及学习成本。
这就导致了这两种开发模式也许并不是很小型应用。
(1)降低耦合度(2)模块职责划分明显(3)利于测试驱动开发(4)代码复用(5)隐藏数据(6)代码灵活性
仔细看我上面那个登录界面,然后回答:
然后你想象我们有登录与清除的功能,那你的User中需要有什么方法?
? public class User { private String username ; private String password ; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }
思考:我们已经有一个User Been了,我们需要用这个User进行什么操作?并将User即将进行的操作写为抽象方法。
public interface IUserBiz { public void login(String username, String password, OnLoginListener loginListener); }
思考:我们之前创建的IUserBiz接口中的方法有哪种情况会发生?并将可能会出现的情况进行写入抽象Listener中去。
public interface OnLoginListener { void loginSuccess(User user); void loginFailed(); }
就是将方法实现
public class UserBiz implements IUserBiz { @Override public void login(final String username, final String password, final OnLoginListener loginListener) { //模拟子线程耗时操作 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //模拟登录成功 if ("123".equals(username) && "123".equals(password)) { User user = new User(); user.setUsername(username); user.setPassword(password); loginListener.loginSuccess(user); } else { loginListener.loginFailed(); } } }.start(); } }
根据接口并实现
public class UserLoginActivity extends ActionBarActivity implements IUserLoginView { private EditText mEtUsername, mEtPassword; private Button mBtnLogin, mBtnClear; private ProgressBar mPbLoading; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_login); initViews(); } private void initViews() { mEtUsername = (EditText) findViewById(R.id.id_et_username); mEtPassword = (EditText) findViewById(R.id.id_et_password); mBtnClear = (Button) findViewById(R.id.id_btn_clear); mBtnLogin = (Button) findViewById(R.id.id_btn_login); mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading); mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.login(); } }); mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.clear(); } }); } @Override public String getUserName() { return mEtUsername.getText().toString(); } @Override public String getPassword() { return mEtPassword.getText().toString(); } @Override public void clearUserName() { mEtUsername.setText(""); } @Override public void clearPassword() { mEtPassword.setText(""); } @Override public void showLoading() { mPbLoading.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mPbLoading.setVisibility(View.GONE); } @Override public void toMainActivity(User user) { Toast.makeText(this, user.getUsername() + " login success , to MainActivity", Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show();
在MVP中Presenter将Model与View进行一个连接,在这个地方的Presenter属于一个中间人的传话的效果。
那么在这个Presenter类中,主要就是图中Button的方法,也就是一个login方法,一个clear方法,具体实现还是将之前所实现的接口进行一个方法对接。
//将**View**与**Model**之间进行操作。 public class UserLoginPresenter { private IUserBiz userBiz; private IUserLoginView userLoginView; private Handler mHandler = new Handler(); ////传递一个loginView public UserLoginPresenter(IUserLoginView userLoginView) { //这个是View的代表 this.userLoginView = userLoginView; //这个是Model的代表 this.userBiz = new UserBiz(); } //下面有两个方法主要是将两个**Button**的操作直接封装完成,然后直接使用 public void login() { userLoginView.showLoading(); userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final User user) { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginFailed() { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailedError(); userLoginView.hideLoading(); } }); } }); } // //这个是clear按钮 public void clear() { userLoginView.clearUserName(); userLoginView.clearPassword(); } }
解答
仔细看我上面那个登录界面,然后回答:
回答:
1.User有userName与password两个属性。
2.userName与password拥有setget方法即可。
思考:我们已经有一个User Been了,我们需要用这个User进行什么操作?
并将User即将进行的操作写为抽象方法。
回答: User需要有一个login的功能,这个功能中我们需要将我们的账号密码传递进 去,同时还有一个Listener需要监听login的情况,在下面就是Listener的创 建了。
思考:我们之前创建的IUserBiz接口中的方法有哪种情况会发生?
并将可能会出现的情况进行写入抽象Listener中去。
回答: 以前接口中主要实现了一个login的功能,这个功能会有两种可能发生,第一 种就是登录成功,第二种就是登录失败。
就是将方法实现。
仔细看我上面那个登录界面,然后回答:
回答:
1.点击login会有登录成功或者登录失败,在这里登录需要获取Edit的信息。
2.点击clear会清除EditView。
那么方法如下:
登录成功方法
登录失败方法
获取UserName
获取PassWord
清除Edit框
根据接口并实现。
在MVP中Presenter将Model与View进行一个连接,在这个地方的Presenter属于一个中间人的传话的效果。
那么在这个Presenter类中,主要就是图中Button的方法,也就是一个login方法,一个clear方法,具体实现还是将之前所实现的接口进行一个方法对接。
标签:public handle 功能 ui线程 prot 而在 ast 可视化 复用
原文地址:http://www.cnblogs.com/loaderman/p/6440554.html