美文网首页
Android MVP设计模式

Android MVP设计模式

作者: 牧头码尾 | 来源:发表于2018-04-04 09:31 被阅读30次

一,前言:

关于Android程序的构架, 当前最流行的模式即为MVP模式, Google官方便提供了Sample代码来展示这种模式的用法.Repo地址: android-architecture.
之所以人们会提到MVP这种设计模式,是因为它与传统的MVC模式相比,使得view层与model层完全解耦,作为view层的activity或者fragment不再臃肿,特别是交互逻辑比较复杂的情况下尤为明显。

二,MVC与MVP对比:

对于MVC与MVP的比较,网上有许多资料,我这里就不详细阐述了,下面就通过两种模式的对比图来简单的总结一下吧。

MVC模式图 MVP模式图
总结:

MVC中的视图和数据是互相耦合在一起的,只要对其中一部分加以改动,其他和之相关的数据和视图都要受到牵连;而MVP中的数据和视图则是通过中间的presenter来连接的。View不直接与Model交互 ,而是通过与Presenter交互来与Model间接交互。通常Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。

三,简单案例

一开始接触MVP设计模式时,也是有点分不清头脑,主要是其中相关的类变多了,各种接口和实现类,有点让人抓狂。后面通过参考了网上几遍相关的案例文章,自己总结了一下,按照一定的思路来写,还是清楚很多。下面我就把自己总结的方法一步步通过案例来实现下,有不足之处,还望大家指正。

文中例子是个简单的请求网络,获取天气的情景。废话不多说,先看实现步骤。

步骤一:先根据业务要求,思考界面主要有哪些实现及展示效果,从而设计view层的接口

/**
 * 定义界面的一些行为状态
 * Created by Administrator on 2018/4/2.
 */

public interface IgetWeatherView {
    void showLoading();
    void hideLoading();
    void getWeatherFialed();//获取天气失败
    void getWeatherSuccess(WeatherBean.WeatherInfo weatherInfo);//获取天气成功
    void displayWeatherInfo(WeatherBean.WeatherInfo weatherInfo);//展示天气结果
}

步骤二:根据需要的获取的数据,定义数据层的基本接口

public interface IWeahter {
    void getWeatherInfo(Context mContext,String url, WeatherListener weatherListener);
   /**
     * 获取天气结果接口回调
     */
    interface WeatherListener{
        void getSuccess(WeatherBean.WeatherInfo weatherBean);
        void getFailed();
    }
}

步骤三:设置数据获取的实现类(真实获取数据的地方)

public class WeatherImpl implements IWeahter{

    @Override
    public void getWeatherInfo(Context mContext, String url, final WeatherListener weatherListener) {
        VolleyRequestUtil.requestGet(mContext, url, "weather", WeatherBean.class, new VolleyListenerInterface(mContext,
                VolleyListenerInterface.mListener,VolleyListenerInterface.mErrorListener) {
            @Override
            public void onSuccess(Object result) {
                WeatherBean weatherBean = (WeatherBean) result;
                weatherListener.getSuccess(weatherBean.weatherinfo);
            }

            @Override
            public void onError(VolleyError error) {
                weatherListener.getFailed();
            }
        });
    }

}

步骤四:设计提供逻辑交互的presenter层,该层必须持有view和model层的引用,然后在逻辑交互过程中把两者进行关联。

public class WeatherPresenter {

    private IWeahter iweather;
    private IgetWeatherView getWeatherView;

    public WeatherPresenter (IgetWeatherView  getWeatherView){
        this.getWeatherView= getWeatherView;
        iweather= new WeatherImpl();
    }

    /**
     * 获取天气信息
     * @param context
     */
    public void getWeatherInfo(Context context){
        getWeatherView.showLoading();
        iweather.getWeatherInfo(context, "http://www.weather.com.cn/data/sk/101010100.html", new IgetWeatherView .WeatherListener() {
            @Override
            public void getSuccess(WeatherBean.WeatherInfo weatherInfo) {
                getWeatherView.hideLoading();
                getWeatherView.getWeatherSuccess(weatherInfo);
                getWeatherView.displayWeatherInfo(weatherInfo);
            }

            @Override
            public void getFailed() {
                getWeatherView.hideLoading();
                getWeatherView.getWeatherFialed();
            }
        });
    }

步骤五,view层的实现(Activity)。有了presenter,activity的具体实现只要实现view层的基本接口即可,剩下的只是利用presenter做简单的界面实现

public class MainActivity extends FragmentActivity implements IgetWeatherView{

    private Button request_btn;
    private TextView display_weather_tv;
    private WeatherPresenter weahterPresenter;
    private ProgressBar progressbar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initListener();
    }

    private void initView() {
        display_weather_tv = (TextView) findViewById(R.id.display_weather_tv);
        request_btn= (Button) findViewById(R.id.request_btn);
        progressbar= (ProgressBar)findViewById(R.id.progressbar);
        weahterPresenter= new WeatherPresenter(this);
    }

    private void initListener() {
        request_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                weahterPresenter.getWeatherInfo(MainActivity.this);

            }
        });
    }

    @Override
    public void showLoading() {
        progressbar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        progressbar.setVisibility(View.GONE);
    }

    @Override
    public void getWeatherFialed() {
        Toast.makeText(this,"获取天气信息失败",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void getWeatherSuccess(WeatherBean.WeatherInfo weatherInfo) {
        Log.d("TAG", "city is " + weatherInfo.getCity());
        Log.d("TAG", "temp is " + weatherInfo.getTemp());
        Log.d("TAG", "time is " + weatherInfo.getTime());
    }

    @Override
    public void displayWeatherInfo( WeatherBean.WeatherInfo weatherInfo) {
        display_weather_tv.setText("city is "+weatherInfo.getCity() +
                "temp is "+weatherInfo.getTemp() +
                "time is "+weatherInfo.getTime());
    }

最后的话:

上述例子中只贴了核心代码,其中网络是自己分装的volley请求,这部分内容以后有时间再总结一下。使用MVP模式后发现,代码量和类确实变多了,不过回过头来,看activity的代码,确实简洁了很多。可能这个例子还不是很明显,不过对于项目比较大,界面逻辑比较多的情况下,使用MVP的模式的确能放大其优势。不过,最终,在自己的项目中该使用什么模式,还是取决于具体项目大小以及复杂程度,还有团队的协作情况。总之,没有最好的模式,只有最适合团队的模式。不过,作为一名android开发者,每一种设计模式都应该了解,这样在将来要用到的时候才能随心所欲的使用,不至于犯怵。好了,关于MVP设计模式就写到这里,大家有什么疑问的,欢迎一起交流学习。

相关文章

网友评论

      本文标题:Android MVP设计模式

      本文链接:https://www.haomeiwen.com/subject/jzychftx.html