为什么软件开发需要使用架构?
软件开发的黄金法则是避免创建上帝类(无所不知无所不能的上帝类),因为上帝类的维护成本很高,我们很难理解正在进行的操作并且难于测试和扩展;
在Android开发中,如果不考虑架构,activity类就会越来越大,因为activity中同时存在业务逻辑和UI逻辑,这会增加更多的维护成本.
- MVC模式:
MVC最初是由微软提出来的,应用于桌面程序中,MVC模式的结构分为,Model实体层的,View视图层,Controller控制层
可以理解为 当用户发出事件的时,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据后直接显示在view层上
MVC中View可以与Controller和Model直接交互.在Android系统中,这样会让view持有Controller和Model的引用; 并且我们把业务逻辑放在Controller层(Android的Activity&Fragment承担Controller控制层的角色),会造成Controller层非常复杂,Activity同时有对UI的操作逻辑,如果项目越来越大,Controller层的代码会更加臃肿,维护起来也更加麻烦
在Android系统中,MVP模式可以说是MVC模式的一种进化
- MVP模式(Model-View-Presenter):
MVP中View不直接与Model交互,而是通过与Presenter来与Model间接交互,Presenter与View的交互是通过接口来进行的,更有利于添加单元测试.
View: 负责绘制UI元素、与用户进行交互(Android中体现可能是Activity或Fragment)
Model: 负责存储、检索、操纵数据(通常实现一个Model interface来降低耦合)
Presenter: 处理View与Model之间的交互,也就是Model层的数据获取及View层的UI显示
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
- MVP架构的利弊?
产品迭代开发中,Activity类的职责不断增加,从而变得庞大臃肿,MVP将其复杂的逻辑处理移到另一个类Presneter中,而activity就是mvp中的view,负责UI初始化和UI展示,建立UI元素与presenter的关联.
利: View与Model都是通过接口交互,方便单元测试;降低以往Activity的职能,减少Activity代码,使代码逻辑更清晰,便于维护和Review
弊: 增加了很多类,代码量大
MVP架构伪代码Sample
- Model
/**
* Model层接口
*/
public interface IModel {
void getData1(ICallback callback);
void getData2(ICallback callback);
interface ICallback {
void onSuccess(String data);
void onFailure(String error);
}
}
/**
* 实现IModel接口,实现获取数据具体逻辑
*/
public class Model implements IModel {
@Override
public void getData1(final ICallback callback) {
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(5000); // 模拟获取数据
callback.onSuccess("获取数据 成功 ");
} catch (InterruptedException e) {
e.printStackTrace();
callback.onFailure("获取数据 失败");
}
}
}.start();
}
public void getData2(final ICallback callback) {
}
}
- View
/**
* View层接口
*/
public interface IView {
void onProgressLoading(int progress);
void showText(String data);
}
/**
* 实现IView接口,实现ui操作具体逻辑
*/
public class ViewActivity extends Activity implements IView {
private ProgressBar progressBar;
private TextView infoText;
private IPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化控件
// progressBar = null;
// infoText = null;
// 初始化Presenter
mPresenter = new MyPresenter();
mPresenter.attachView(this);
// 实现仅仅通过Presenter来处理业务逻辑
mPresenter.doWork1();
}
@Override
public void onProgressLoading(int progress) {
// UI展示 业务处理中
progressBar.setProgress(progress);
}
@Override
public void showText(String data) {
// UI展示 业务处理完成结果
infoText.setText(data);
}
@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.detachView();
}
}
- Presenter
public abstract class BasePresenter<V extends IView, M extends IModel> {
protected V view;
protected M model;
public BasePresenter() {
model = createModel();
}
@UiThread
void attachView(V view) {
this.view = view;
}
@UiThread
void detachView() {
this.view = null;
}
abstract M createModel();
}
/**
* Presenter层接口
*/
public abstract class IPresenter extends BasePresenter<IView, IModel> {
abstract void doWork1();
abstract void doWork2();
}
/**
* 实现IPresenter接口,处理Model层的数据获取及View层的UI显示
*/
public class MyPresenter extends IPresenter {
@Override
IModel createModel() {
return new Model();
}
@Override
public void doWork1() {
view.onProgressLoading(0);
model.getData1(new IModel.ICallback() {
@Override
public void onSuccess(String data) {
// 数据获取成功回调
view.showText(data);
}
@Override
public void onFailure(String error) {
// 数据获取失败回调
view.showText(error);
}
});
view.onProgressLoading(100);
}
@Override
void doWork2() {
}
@Override
public void detachView() {
view = null;
}
}