1. 程式人生 > >策略模式實現 retrofit 的get和post請求的公共引數(一)

策略模式實現 retrofit 的get和post請求的公共引數(一)

策略模式的作用,作用是替換if,elst if ,switch case,可是為什麼我就替換不了呢?

比如:
圖書價格,初級會員9折,高階會員打8折
通常實現:

private double getPrice(int grade, double price) {
        switch (grade) {
            case 1:
                //初級會員
                price = price * 0.9;
                break;
            case 2:
                //高階會員
price = price * 0.8; break; } return price; } //或者 private double getPrice(int grade, double price) { if (grade == 1) { price = price * 0.9; } else if (grade == 2) { price = price * 0.8; } return
price; } //或者 private double getPrice(int grade, double price) { if (grade == 1) { return price * 0.9; } if (grade == 2) { return price * 0.8; } return price; } 當然第三種寫法沒必要

策略模式實現:

public interface IPrice {
    public double calcPrice
(double price); } //初級 public class Primary implements IPrice{ @Override public double calcPrice(double price) { return price * 0.9; } } //高階 public class Senior implements IPrice{ @Override public double calcPrice(double price) { return price * 0.8; } } //上下文 public class PriceContext { private IPrice iPrice; public PriceContext(IPrice iPrice){ this.iPrice = iPrice; } public double count(double price){ return iPrice.calcPrice(price); } } //客戶端(需求:根據會員等級判斷,得到相應的一個價格) 方案一: private double getPrice(int grade, double price) { price = new PriceContext(new Primary()).count(price); price = new PriceContext(new Senior()).count(price); return price; } 方案一相當於 if(1){初級會員} if(2){高階會員} 也就是說其中一個方案得到價格後,仍然會去判斷第二個,當然不是我想要的 方案二: private double getPrice(int grade, double price) { switch (grade) { case 1: //初級會員 price = new PriceContext(new Primary()).count(price); break; case 2: //高階會員 price = new PriceContext(new Senior()).count(price); break; } return price; } 貌似符合要求了,但是策略模式就是為了解決if elseif switch case 的啊, 怎麼用了策略模式我還是寫了switch case 如果此時我想增加一箇中級會員,是不是要再加一個case,說好的開閉原則呢?

我們期望的:
新增一箇中級會員,我不想修改客戶端

//好辦,還有一個上下文可以修改,我們把客戶端的程式碼放在客戶端就好了
public class PriceContext {
    private IPrice iPrice;
    private int grade;
    public PriceContext(int grade){
        this.grade = grade;
    }

    public double count(double price){
        switch (grade) {
            case 1:
                //初級會員
                iPrice = new Primary();
                break;
            case 2:
                //高階會員
                iPrice = new Senior();
                break;
        }

        return iPrice.calcPrice(price);
    }
}
//客戶端
private double getPrice(int grade, double price) {
price = new PriceContext(grade).count(price);
return price;
}
此時如果增加一箇中級會員,直接在Context中增加一個case即可,客戶端無需修改

下面進入正題,同樣的方法實現retrofit在get和post中的公共引數配置

retrofit中公共引數是通過攔截器進行配置的

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(factory.initQuery(context));

//公共引數
    public Interceptor initQuery(final Context context) {


        Interceptor addQueryParameterInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                //配置公共引數
                request = new ParamsContext(request, context).getInRequest();
                return chain.proceed(request);
            }
        };
        return addQueryParameterInterceptor;
    }

照葫蘆畫瓢

public interface IRequestParam {

    Request getRequest(Request request, Context context);
}

//get
public class GetRequestParams implements IRequestParam {
    @Override
    public Request getRequest(Request request, Context context) {

        //新增公共引數
        HttpUrl modifiedUrl = request.url().newBuilder()
                .addQueryParameter(CLIENT, AppTools.getClient(context))
                .addQueryParameter(VERSION, AppTools.getAppVersion(context))
                .addQueryParameter(TOKEN, AppTools.getToken(context))
                .build();

        return request.newBuilder().url(modifiedUrl).build();
    }
}

//post
public class PostRequestParams implements IRequestParam {
    @Override
    public Request getRequest(Request request, Context context) {

        if (request.body() instanceof FormBody) {
            FormBody.Builder bodyBuilder = new FormBody.Builder();

            FormBody formBody = (FormBody) request.body();

            for (int i = 0; i < formBody.size(); i++) {
                bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
            }
            formBody = bodyBuilder.addEncoded(CLIENT, AppTools.getClient(context))
                    .addEncoded(VERSION, AppTools.getAppVersion(context))
                    .addEncoded(TOKEN, AppTools.getToken(context))
                    .build();
            request = request.newBuilder().post(formBody).build();
        }
        return request;
    }
}

//上下文
public class ParamsContext {

    private IRequestParam iRequestParam;
    private Context context;
    private Request request;

    public ParamsContext(Request request, Context context) {
        this.context = context;
        this.request = request;
    }

    public Request getInRequest() {
        switch (request.method()) {
            case "GET":
                iRequestParam = new GetRequestParams();
                break;
            case "POST":
                iRequestParam = new PostRequestParams();
                break;
        }
        return iRequestParam.getRequest(request, context);
    }
}