策略模式实战篇

我们使用 MVP + 策略模式模拟一个简单的登录功能

MVP + retorfit + rx 请求策略简单的 UML

首先我们要使用 AsyncHttpClient、Retorfit 等,先添加配置 Gradle「项目 Module 的 build.grade中」

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.1.5'
compile 'com.loopj.android:android-async-http:1.4.9'

注: 以下代码纯粹是为了演示策略模式,顺手写的,好多细节可能没有考虑到,但是基本框架就是这样的,可以自行完善

  • 1、分别新建 MVP 的基类接口,IPresenter,Model,IView
/**
 * @Description MVP 中的 Presenter 基
 * @Creator TigerChain(创建者)
 */
public interface Presenter {
}


/**
 * @Description MVP 中的 Model 基类
 * @Creator TigerChain(创建者)
 */
public interface Model {
}

/**
 * @Description MVP 中的 View 基类
 * @Creator TigerChain(创建者)
 */
public interface IView {
}

  • 2、新建 MVP 的关联接口 ILoginContact.java 「当然也可以不写此类,直接写登录 MVP 的直接子类」
package designpattern.tigerchain.com.mvphttpstrategy.mvp;

import designpattern.tigerchain.com.mvphttpstrategy.mvp.domain.User;
import io.reactivex.Observable;

/**
 * @Description MVP 的关联类「也可以单独创建 MVP 就是有点乱」
 * @Creator TigerChain(创建者)
 */
public interface ILoginContact {

    interface LoginView extends IView{
        //显示进度条
        void showProgress() ;
        //隐藏进度条
        void hideProgress() ;
        //登录成功
        void loadSuccess(String str) ;
        //登录失败
        void loadFailed(String str) ;
        //取得用户名
        String getUserName() ;
        //取得用户密码
        String getUserPass() ;
        //清除输入框
        void clearEditText() ;
        //用户名和密码不能为空
        void editnotNull() ;
    }

    interface LoginPresenter extends Presenter{类
        /**
         * 登录功能
         */
        void login() ;

        /**
         * 清除输入框架内容
         */
        void clear() ;
    }

    interface ILoginModel extends Model{
        /***
         * 登录的方法,其实这里就是一个抽象策略,至于你使用 retrofit 还是 asynchttpClient 还是 Volley 那是自己的事情
         * @param uName
         * @param uPass
         * @return
         */
        Observable<User> login(String uName, String uPass) ;
    }
}


其中 ILoginModel 就是一个抽象策略,这里是登录功能

  • 3、分别实现具体的策略「使用不同的网络请求库调用登录 API」
  • 具体策略1:使用 AsyncHttpClient 调用登录
/**
 * @Description 具体策略使用 AsyncHttpClient 来调用登录 API
 * @Creator TigerChain(创建者)
 */
public class AsynchHppClientImplLogimModel implements ILoginContact.ILoginModel {

    @Override
    public Observable<User> login(final String uName, final String uPass) {
        return Observable.create(new ObservableOnSubscribe<User>() {
            @Override
            public void subscribe(final ObservableEmitter<User> e) throws Exception {

                AsyncHttpClient client = new AsyncHttpClient() ;
                // 这里就是一个请求 没有真正的对接服务器,只是一个演示
                client.get("http://www.baidu.com", new AsyncHttpResponseHandler() {
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                        if(uName.equalsIgnoreCase("TigerChain") && uPass.equals("123")){
                            User user = new User() ;
                            user.setuName(uName);
                            user.setUpass(uPass);
                            e.onNext(user);
                            e.onComplete();
                        }else{
                            e.onNext(null);
                            e.onComplete();
                        }
                    }

                    @Override
                    public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                        e.onError(error);
                    }
                }) ;
            }
        });
    }
}
  • 具体策略2:使用 Volley 调用登录 API
/**
 * @Description 具体策略使用 Volley 实现登录功能
 * @Creator TigerChain(创建者)
 */
public class VolleyImplLoginModel implements ILoginContact.ILoginModel {

    @Override
    public Observable<User> login(final String uName, final String uPass) {
        return Observable.create(new ObservableOnSubscribe<User>() {
            @Override
            public void subscribe(final ObservableEmitter<User> e) throws Exception {

                /***
                 * 这里调用和 Volley 相关的 API 实现登录即可
                 */
            }
        });
    }
}
  • 具体策略3:使用 RetorFit 调用登录 API
/**
 * @Description 具体策略 使用 RetorFit 实现登录功能性
 * @Creator TigerChain(创建者)
 */
public class RetorFitImplLoginModel implements ILoginContact.ILoginModel {

    @Override
    public Observable<User> login(final String uName, final String uPass) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://")
                .build();
        ILoginRetorfitApi loginService = retrofit.create(ILoginRetorfitApi.class) ;
        return loginService.login(uName,uPass) ;
    }
}

其中 User 和 ILoginRetorfitApi 类分别是:

# User.java

/**
 * @Description 普通人的 Java
 * @Creator TigerChain(创建者)
 */
public class User {

    private String uName ;
    private String Upass ;

    public String getuName() {
        return uName;
    }

    public void setuName(String uName) {
        this.uName = uName;
    }

    public String getUpass() {
        return Upass;
    }

    public void setUpass(String upass) {
        Upass = pass;
    }
}

# ILoginRetorfitApi.java
/**
 * @Description Retrofit API
 * @Creator TigerChain(创建者)
 */
public interface ILoginRetorfitApi {

    @GET("/login")
    Observable<User> login( @Field("userName") String userName,
                            @Field("passWord")String passWord) ;
}

  • 4、策略中的上下文「这里就是我们具体的 P」 LoginPresenterImpl.java
/**
 * @Description MVP 中的P ,就相当于策略中Context
 * @Creator junjun(创建者)
 */
public class LoginPresenterImpl implements ILoginContact.LoginPresenter {

    private ILoginContact.ILoginModel iLoginModel ;
    private ILoginContact.LoginView loginView ;

    public LoginPresenterImpl(ILoginContact.LoginView loginView,ILoginContact.ILoginModel iLoginModel){
        this.iLoginModel = iLoginModel ;
        this.loginView = loginView ;
    }

    @Override
    public void login() {

        String uName = loginView.getUserName() ;
        String uPass = loginView.getUserPass() ;

        if(TextUtils.isEmpty(uName) || TextUtils.isEmpty(uPass)){
            loginView.editnotNull();
            return ;
        }
        loginView.showProgress();
        iLoginModel.login(uName,uPass)
//                subscribeOn(Schedulers.io()) 由于 AsyncHttpClient 本身就是在子线程去请求的,所以这里为了演示把这个去掉
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<User>() {

                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(User user) {
                        loginView.loadSuccess("登录成功");

                    }

                    @Override
                    public void onError(Throwable e) {
                        loginView.loadFailed("用户名或密码错误,登录失败");
                        loginView.hideProgress();
                    }

                    @Override
                    public void onComplete() {
                        loginView.hideProgress();
                    }
                }) ;
    }

    @Override
    public void clear() {
        loginView.clearEditText();
    }
}

到此为止,我们的 MVP+RX+Retorfit 带策略的登录功能就完成了。

  • 5、客户端调用「在 Activity 中调用」

下面来看客户调用,不贴代码了「放一张部分代码截图」,后面放出全部 DEMO 大家自行查看

怎么样,通过以上几个例子,相信我们对策略模式有了很好的理解了

  • 6、最后运行看一下

demo 没有实现完毕,其中 Retorfit 和 Volley 没有完善,有兴趣的可以自行完善。

完整的项目代码地址:

https://github.com/buder-cp/DesignPattern/tree/master/mvp-rx-loginStrategy-master

发布了189 篇原创文章 · 获赞 81 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/102922935