[英]Android: how to use Code to interface design pattern to have multiple implementations of network call libraries(Retrofit or volley)
我正在從 Head First Design Patterns 學習設計模式,我遇到的第一個模式是“代碼到界面”。現在我想在我的 android 應用程序中使用該模式。我的應用程序包含很多 api 調用。我正在使用 Retrofit用於網絡調用。所以我使用了這種設計模式,考慮到一些類似這樣的場景:
1. 假設將來我需要從 Retrofit 轉向 volley 或任何其他網絡庫。
2. 所以我創建了一個帶有從服務器獲取數據的方法的接口,並創建了一個實現該接口的類。實現的方法包括從服務器獲取數據的改造代碼。
3. 現在,如果我想使用 volley,我將創建一個實現接口的新類,並使用 volley 代碼從服務器檢索數據。
代碼是這樣的
更新
改造特定接口
public interface RetrofitApi {
@GET
Call<ResponseBody> getDataFromServer(@Url String url);
}
更新
界面
一個具有多個網絡調用庫實現的通用接口(這里我使用的是改造,所以我創建了一個實現這個接口的類 NetworkCallsRetrofitImpl。如果我想切換到 volley,我會創建另一個具有 volley 實現的類並實現這個接口)
public interface NetworkCallsApi {
String getDataFromServer(Activity activity,String url,String Callback);
}
改造實施
public class NetworkCallsRetrofitImpl implements NetworkCallsApi{
private Retrofit retrofit;
@Override
public String getDataFromServer(Activity activity, String url, String Callback) {
retrofit = new Retrofit.Builder()
.baseUrl(StringConstants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi apiCalls = retrofit.create(RetrofitApi.class);
Call<ResponseBody> call = apiCalls.getDataFromServer(url);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Method method = null;
try {
method = fragment.getClass().getDeclaredMethod(
Callback, new Class[]{String.class});
method.invoke(fragment, response.body().string());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
return null;
}
}
服務調用.java
public class ServiceCalls {
public static ServiceCalls serviceCalls;
public NetworkCallsApi networkCallsimpl;
public static ServiceCalls getInstance(){
if(serviceCalls == null){
serviceCalls = new ServiceCalls();
}
return serviceCalls;
}
public void setNetworkCallsimpl(NetworkCallsApi networkCallsimpl) {
this.networkCallsimpl = networkCallsimpl;
}
public String getDataFromServer(Activity activity, String url, String callback){
networkCallsimpl.getDataFromServer(activity,url,callback);
return null;
}
}
主片段代碼:
public class StatusFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the implementation
ServiceCalls.getInstance().setNetworkCallsimpl(new NetworkCallsRetrofitImpl());
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_pnr_status,container,false);
try{
init();
}catch(Exception e){
}
return view;
}
private void init() {
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setUrlKeysAndValues();
ServiceCalls.getInstance().getDataFromServer(getActivity()
,Utils.getInstance().buildUrl(urlKeys,urlValues),"onResponse");
}
});
}
public void onResponse(String response){
String x = response;
try {
JSONObject jsonObject = new JSONObject(x);
String name = jsonObject.getJSONObject("train").getString("name");
String temp = jsonObject.getJSONObject("train").getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
現在我的問題是“我是否正確實現了該設計模式”。如果沒有,我需要做哪些更改。在 MainFragment 代碼的 onCreate 中,我正在對實現進行硬編碼。如何在這種情況下更好地應用接口設計模式的代碼。謝謝.
更新
這里的“字符串回調”只是一個在收到響應后要調用的方法名稱。這個方法寫在片段類中,視圖必須更新。我正在使用 Java 反射調用這個方法。
1) 帶有回調的方法應該沒有返回類型。 無論如何你都返回 null,所以讓它們無效。
2)您最終將需要在 UI 中返回響應來更新您的視圖,因此您應該將回調作為Callback
類傳遞,而不是一些String callback
。
3) 不需要每次調用您的方法時都更新該私有字段。
4)您不需要 Activity 來發出網絡請求(我想回到第 2 點)
5) 我很確定 Retrofit 使用注釋來處理 URL,所以不確定我在getDataFromServer(url)
看到參數的用途。
您更新后的代碼將如下所示。
注意:這不是“編程接口”的展示,也不是任何“設計模式”,它只是“干凈的代碼”(恕我直言)。
無論如何,通過Retrofit.create
方法,改造已經強制執行“編程接口”模式。
public class NetworkCallsRetrofitImpl implements NetworkCallsApi{
private final Retrofit retrofit;
public NetworkCallsRetrofitImpl() {
retrofit = new Retrofit.Builder()
.baseUrl(StringConstants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public void getDataFromServer(String url, Callback<ResponseBody> cb) {
retrofit.create(RetrofitApi.class)
.getDataFromServer(url)
.enqueue(cb);
}
}
// This method seems really pointless, by the way...
public void getDataFromServer(String url, Call<ResponseBody> callback){
networkCallsimpl.getDataFromServer(url,callback);
}
public class StatusFragment extends Fragment implements Callback<ResponseBody> {
private ServiceCalls serviceCalls;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the implementation
serviceCalls = ServiceCalls.getInstance();
serviceCalls.setNetworkCallsimpl(new NetworkCallsRetrofitImpl());
}
private void updateStatus() {
serviceCalls.getDataFromServer("http://site.example/status", this);
}
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String response = response.body().toString();
Toast.makeText(getActivity(), response, TOAST.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("err", t.getMessage());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.