您的位置:首页 > 运维架构 > 网站架构

认识GOOGLE官方架构MVP

2017-05-27 00:00 309 查看

认识GOOGLE官方架构MVP

MVP框架简述

MVP框架分析

实战示范

参考内容

MVP框架简述

MVP由model–view–controller (MVC)软件模式衍生而来,是一个把view从底层分离出来的一种轻量模型。

M(model)代表的是将会显示在view(UI)中的数据。

V(view)是显示数据(model)并且将用户指令(events)传送到presenter以便作用于那些数据的一个接口。View通常含有Presenter的引用。

P(presenter)起到控制的作用,是一个中转元素(如 MVC中的controller),且presenter同时引用view和model。



MVP框架分析

Presenter解耦

Presenter起到的就是转发和控制的作用,如果采用传统的OnClickListener监听来代替Presenter,则无法对View内部元素进行合理的控制,控制逻辑复杂。而Presenter了解View的内部结构,可以有效地进行控制,并保证低耦合。

加之,Presenter不应被绑定到Android平台,Presenter的内容应该是普遍意义上能与其他任何java应用共享的java代码。

View自主权

View只执行Presenter指示的操作,即完全依靠Presenter的控制进行工作,所以在进行接口设计时,应该让Presenter控制View的方式更加抽象,粒度不能够太小。

类图及分析如下



- BaseView

界面需要提供的方法中会有很多类似的,把它们提取到一个公共的父类接口中。比如setPresenter方法,其他的view层接口就可以直接继承BaseView接口,不必做重复工作。

public interface BaseView<T> {
void setPresenter(T presenter);
}


BasePresenter

同理,BasePresenter提供重复的Presenter接口。

public interface BasePresenter {
void start();
}


Contract

工程中,每一个模块都有一个自己的Contract接口,Contract包涵了Presenter和View,Presenter实现的逻辑层方法,View实现的界面层的方法都能在Contract接口中一目了然的看明白,具体的Presenter和View的实现类都是通过实现Contract接口来完成。这种管理办法使得开发和维护十分简单。

public interface XXXContract {
interface View extends BaseView<Presenter> {
}
}
interface Presenter extends BasePresenter {
}
}


实战示范

项目目录

注:实例来自笔者亲身参与的一款运动体验项目

项目结构的组织方式基本按照功能进行划分,之后我们具体关注login模块中MVP的实现用于理解MVP的实现流程。





LoginContract

具体login任务的Presener和View接口,Presenter接口里面封装的是数据获取的方法,需要数据提供者具体实现;View里面封装是界面层(Fragment)要实现的方法。

public interface LoginContract {
interface View extends BaseView<Presenter> {
/**
* 设置加载提示符
*/
void showLoadingIndicator();
/**
* 设置出错信息
*/
void showErrorInfo();
}

interface Presenter extends BasePresenter {
boolean checkAccount(String username, String password);
}
}


LoginPresenter

继承LoginContract.Presenter接口,实现具体的功能方法,代码不再赘述。

LoginActivity

在MVP架构中,个人理解Activity主要负责控制,Fragment负责展示,当然MVP只是一种思想,代码书写的方式因人而异。

LoginActivity的主要只能有初始化Fragment并创建Presenter。

public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_act);
LoginFragment loginFragment = (LoginFragment) getSupportFragmentManager().findFragmentById(R.id.layout_login_content);

if (loginFragment == null) {
loginFragment = loginFragment.newInstance();         ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), loginFragment, R.id.layout_login_content);
}
new LoginPresenter(loginFragment);
}
}


LoginFragment

LoginFragment是View接口的实现类,其不与Model层进行交互,只和presenter的实例进行交互。

LoginFragment持有相应LoginPresenter的引用,通过view的setPresenter方法完成实例的关联操作。当LoginFragment收到界面操作请求即通过LoginPresenter完成逻辑上的处理。

public class LoginFragment extends Fragment implements LoginContract.View {

private LoginContract.Presenter mPresenter;

private EditText edtTxt_userName;

private EditText edtTxt_passWord;

private Button btn_login;

private Button btn_noAccount;

public static LoginFragment newInstance() {
return new LoginFragment();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.login_frag, container, false);
return root;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

btn_login = (Button) getActivity().findViewById(R.id.btn_login);

btn_noAccount = (Button) getActivity().findViewById(R.id.btn_noAccount);

edtTxt_userName = (EditText) getActivity().findViewById(R.id.edtTxt_userName);

edtTxt_passWord = (EditText) getActivity().findViewById(R.id.edtTxt_passWord);

btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean loginResult = mPresenter.checkAccount(edtTxt_userName.getText().toString(), edtTxt_passWord.getText().toString());
if (loginResult) {
getActivity().finish();
Intent intent = new Intent(getActivity(), HomePageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}

}
});

btn_noAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), RegisterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
}

@Override
public void onResume() {
super.onResume();
mPresenter.start();
}

@Override
public void onStop() {
super.onStop();
edtTxt_userName.setText("");
edtTxt_passWord.setText("");
}

@Override
public void showLoadingIndicator() {
Toast.makeText(getActivity().getApplicationContext(), "登录成功",Toast.LENGTH_SHORT).show();
}

@Override
public void showErrorInfo() {
Toast.makeText(getActivity().getApplicationContext(), "用户名或密码错误",Toast.LENGTH_SHORT).show();
}

@Override
public void setPresenter(LoginContract.Presenter presenter) {
mPresenter = presenter;
}
}


参考内容

Github文章:https://github.com/hehonghui/android-tech-frontier

架构图片:http://justjavac.iteye.com/blog/1998210
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mvp 谷歌