android之MVP

一: MVP是什么?

         

     随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责。为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生。
     在MVP模式里通常包含4个要素:
     1. View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
     2. View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
     3. Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
     4. Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。


二:MVP同MVC的区别

           

其实最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的。

三:MVP优缺点

      优点:

          (1)降低耦合度

        (2)模块职责划分明显

        (3)利于测试驱动开发

       (4)代码复用

        (5)隐藏数据

  (6)代码灵活性

  
缺点:
           由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它         与特定的视图的联系过于紧密。一旦视图需要变更,那么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使用实例

        view接口:

public interface MainView{
void showProgress();
void hideProgress();
void setIpText(String text);
}

Presenter接口:
public interface MainPresenter extends BasePresenter {
void getIpInfo(String ip);
}

  Presenter实现类:

	public class MainPresenterImpl extends BasePresenterImpl implements MainPresenter {
    		private static final String TAG = "TAG";
    		private MainView mMainView;

    		public MainPresenterImpl(MainView mainView) {
        		mMainView = mainView;
    		}

    		@Override
    		public void getIpInfo(String ip) {
        		if (TextUtils.isEmpty(ip)) {
            			Toast.makeText(BaseApplication.getContext(), R.string.input_tip_ip, Toast.LENGTH_SHORT).show();
           			 return;
        		}
        		mMainView.setIpText("");
        		mMainView.showProgress();
        		ServiceManager.getInstance().getApiService().getIpInfo(ip)
                		.subscribeOn(Schedulers.io())
                		.observeOn(AndroidSchedulers.mainThread())
                		.subscribe(new Subscriber<GetIpInfoResponse>() {
                    @Override
                    public void onCompleted() {
                        mMainView.hideProgress();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, e.getMessage(), e);
                        mMainView.hideProgress();
                        mMainView.setIpText(BaseApplication.getContext().getString(R.string.network_error));
                    }

                    @Override
                    public void onNext(GetIpInfoResponse getIpInfoResponse) {
                        mMainView.setIpText(getIpInfoResponse.data.country + " " + getIpInfoResponse.data.area);
                    }
                });
    	    }
	}  

	MainActivity:
	
		public class MainActivity extends AppCompatActivity implements MainView {

    			private EditText mEtIp;
    			private TextView mTvContent;
    			private ProgressBar mProgressBar;
    			private MainPresenter mMainPresenter;

    			@Override
    			protected void onCreate(Bundle savedInstanceState) {
        			super.onCreate(savedInstanceState);
        			setContentView(R.layout.activity_main);
        			Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        			setSupportActionBar(toolbar);

        			mEtIp = (EditText) findViewById(R.id.et_ip);
        			mTvContent = (TextView) findViewById(R.id.tv_content);
        			mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        			mMainPresenter = new MainPresenterImpl(this);

        			FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        			fab.setOnClickListener(new View.OnClickListener() {
           				 @Override
            				public void onClick(View view) {
                				mMainPresenter.getIpInfo(mEtIp.getText().toString());
            				}
        			   });
    				}

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void showProgress() {
        mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void setIpText(String text) {
        mTvContent.setText(text);
    }
}  

  1.        



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值