web-dev-qa-db-ja.com

後付けのためにビルダーコードを再利用する方法はありますか

私は Retrofit を使用しており、すべてのタスクで次のようなことをしなければなりません。

public class MyTask extends AsyncTask<String, String, String> {

    private void someMethod() {
        final RestAdapter restAdapter = new RestAdapter.Builder()
            .setServer("http://10.0.2.2:8080")
            .build();
        final MyTaskService apiManager = restAdapter.create(MyTaskService.class);
    }

    // ...

}

このコードをDRYにする良い方法は何ですか?

21
birdy

まず、すべての一般的な動作で親クラスを宣言します

public abstract class MyAbstractTask extends AsyncTask<String, String, String> {

 protected void someMethod() { //note that i change private to protected
  final RestAdapter restAdapter = new RestAdapter.Builder().setServer("http://10.0.2.2:8080").build();
  final MyTaskService apiManager = restAdapter.create(MyTaskService.class);
 }

}

次に、すべてのタスクでそれを拡張します

public   class MyTask extends MyAbstractTask {

 //your someMethod() is available from everywhere in your class

}

public  class MyOtherTask extends MyAbstractTask {

 //your someMethod() is available from everywhere in your class

}

しかし、restAdapterとapiManagerをどこで使用しているか、実際にタスクごとに1回作成する必要があるかどうかはわかりません。おそらく、これらのタスクの外部で作成できるからです。

それらを外部で作成し、タスク内で何かを使用する必要がある場合は、 Dependency_injection パターンを念頭に置くこともお勧めします。


また、http://10.0.2.2:8080のようなクラスの値をハードコーディングすることは避けてください。

少なくともfinal static final String server= "http://10.0.2.2:8080"を使用してから、それを使用するか、最も内側のクラスのセッターまたはコンストラクターを使用して、アクティビティまたはメインコントローラーから値を設定する必要があります。

5
Carlos Robles

RestAdapterとサービスの生成されたインスタンス(この場合はMyTaskService)はどちらも非常に高価なオブジェクトであり、シングルトンとして使用する必要があります。

つまり、restAdapter.createを1回だけ呼び出して、対話する必要があるたびにMyTaskServiceの同じインスタンスを再利用する必要があります。

私はこれを十分に強調することはできません。

通常のシングルトンパターンを使用して、どこでも使用するこれらのオブジェクトのインスタンスが1つだけになるようにすることができます。依存性注入フレームワークも、これらのインスタンスを管理するために使用できるものですが、まだ使用していない場合は少しやり過ぎになります。

45
Jake Wharton

ジェイクが言ったように、同じインスタンスが常に使用されるようにするには、 シングルトンパターン を使用する必要があります。

次に例を示します。

public class ApiManager {

    public interface GitHubService {

        @GET("/users/{user}/repos")
        List<Repo> listRepos(@Path("user") String user);

    }

    private static final String API_URL = "https://api.github.com";

    private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
        .setEndpoint(API_URL)
        .setLogLevel(LogLevel.FULL)
        .build();

    private static final GitHubService GIT_HUB_SERVICE = REST_ADAPTER.create(GitHubService.class);

    public static GitHubService getService() {
        return GIT_HUB_SERVICE;
    }
}

この例では、次のようにサービスを使用できます。

ApiManager.getService().listRepos(...);
45
Gautam