java - 我如何才能 DRY Android 改造调用?

标签 java android retrofit2 dry

我的代码中有几个存储库类。

例如,这是 UserRepository:

public class UserRepository {

public static String TAG = "UserRepository";

ApiService mApiService;

SharedPreferences mPrefs;
Context mContext;

RemoteDataSource<User> mRemoteDataSource;


public UserRepository() {
    mApiService = new RetrofitClient().getApiService();
    mContext = App.getAppContext();
    mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    mRemoteDataSource = new RemoteDataSource<>();
}

public RemoteDataSource getRemoteDataSource() {
    mRemoteDataSource.setIsLoading();
    Call<ApiResponse> userCall = mApiService.getUserInfo(mPrefs.getString(User.TOKEN_NAME, null));
    userCall.enqueue(new Callback<ApiResponse>() {
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
            mRemoteDataSource.setIsLoaded();
            mRemoteDataSource.setData(response.body().getUser());
            mRemoteDataSource.setStatus(response.body().getStatus());
            mRemoteDataSource.setMessage(response.body().getMessage());
        }

        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
            Log.e(TAG, t.getMessage());
            mRemoteDataSource.setFailed(t.getMessage());
        }
    });

return mRemoteDataSource;
}

}

这是 BonusRepository:

public class BonusRepository {

public static String TAG = "BonusRepository";

ApiService mApiService;

SharedPreferences mPrefs;
Context mContext;

LiveData<Bonus> mBonus;
String mId;
RemoteDataSource<Bonus> mRemoteDataSource;

public BonusRepository(String id) {
    mId = id;
    mApiService = new RetrofitClient().getApiService();
    mContext = App.getAppContext();
    mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    mRemoteDataSource = new RemoteDataSource<>();
}

public RemoteDataSource getRemoteDataSource() {
    mRemoteDataSource.setIsLoading();
    Call<ApiResponse> bonusCall = mApiService.getBonus(mPrefs.getString(User.TOKEN_NAME, null), mId);
    bonusCall.enqueue(new Callback<ApiResponse>() {
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
            mRemoteDataSource.setIsLoaded();
            mRemoteDataSource.setData(response.body().getBonus());
            mRemoteDataSource.setStatus(response.body().getStatus());
            mRemoteDataSource.setMessage(response.body().getMessage());
        }

        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
            Log.e(TAG, t.getMessage());
            mRemoteDataSource.setFailed(t.getMessage());
        }
    });
    return mRemoteDataSource;
}
}

getRemoteDataSource 两个类中的方法是相同的,除了

Call<ApiResponse> userCall = mApiService.getUserInfo(mPrefs.getString(User.TOKEN_NAME, null));

mRemoteDataSource.setData(response.body().getUser()); 在 UserRepository 中

区别于:

Call<ApiResponse> bonusCall = ApiService.getBonus(mPrefs.getString(User.TOKEN_NAME, null), mId);

mRemoteDataSource.setData(response.body().getBonus()); 在 BonusRepository 中。

在其他存储库中我有类似的重复代码。

我想删除这个重复项,但没有找到任何好的解决方案。

DRY 我的代码的最佳方法是什么?

最佳答案

为所有存储库创建一个父抽象类,并实现 getRemoteDataSource() 方法,调用一个新的抽象方法,这将是每个特定实现中唯一的特定方法。

例如:

public class AbstractRepository {

protected abstract Call<ApiResponse> performCall();

public RemoteDataSource getRemoteDataSource() {
    mRemoteDataSource.setIsLoading();
    Call<ApiResponse> userCall = performCall();
    userCall.enqueue(new Callback<ApiResponse>() {
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
            mRemoteDataSource.setIsLoaded();
            mRemoteDataSource.setData(response.body().getUser());
            mRemoteDataSource.setStatus(response.body().getStatus());
            mRemoteDataSource.setMessage(response.body().getMessage());
        }

        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
            Log.e(TAG, t.getMessage());
            mRemoteDataSource.setFailed(t.getMessage());
        }
    });

return mRemoteDataSource;
}

}

然后你可以执行类似的操作:

public class UserRepository extends AbstractRepository {

public static String TAG = "UserRepository";

ApiService mApiService;

SharedPreferences mPrefs;
Context mContext;

RemoteDataSource<User> mRemoteDataSource;

public UserRepository() {
    mApiService = new RetrofitClient().getApiService();
    mContext = App.getAppContext();
    mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    mRemoteDataSource = new RemoteDataSource<>();
}

protected Call<ApiResponse> performCall() {
    return mApiService.getUserInfo(mPrefs.getString(User.TOKEN_NAME, null));
}

我让你适应你的需求,但这是最好的解决方案。

关于java - 我如何才能 DRY Android 改造调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53258088/

相关文章:

java - Spring MVC、Maven、Pivo​​tal tc 服务器 HTML 404 未找到错误

android - 在 Android Studio 上添加 Google Play 服务依赖项的最佳方式是什么?

android - 如何为 inflatedView (按钮)设置动态宽度和高度

Android:更新 SDK 管理器后出现问题

java - Retrofit2 + RxJava2 全局处理错误

android - 如何在 Android 的 Retrofit 库中设置连接超时?

android - Kotlin Android Retrofit 2.6.0 与协程错误处理

java - Spring 启动: @Profile @Bean combination doesn't work

java - 无法在 JDBC 中执行 MySQL 存储过程,出现空指针异常

java - Xcode 4.5.1 : Linker Error: NSJavaVirtualMachine, 找不到体系结构 i386 的符号