Подтвердить что ты не робот

Есть ли способ повторно использовать код строителя для переоснащения

Я использую 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);
    }

    // ...

}

Что такое хороший способ сделать этот код СУХОЙ?

4b9b3361

Ответ 1

сначала вы объявляете свой родительский класс со всем распространенным поведением

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, и если на самом деле нужно создать один раз для каждой задачи, поскольку, возможно, вы можете создать его за пределами этих задач.

Если вы создаете их снаружи, а затем вам нужно что-то использовать внутри своей задачи, также полезно иметь в виду Dependency_injection.


Кроме того, вы должны избегать значений жесткого кодирования в своих классах, например http://10.0.2.2:8080

Вы должны использовать по крайней мере a final static final String server= "http://10.0.2.2:8080", а затем использовать это или, лучше, использовать установщик или конструктор в самом внутреннем классе и задавать значения из активности или основного контроллера.

Ответ 2

Как сказал Джейк, вы должны использовать шаблон singleton, чтобы гарантировать, что тот же самый экземпляр всегда используется.

Вот пример:

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(...);

Ответ 3

Оба RestAdapter и сгенерированный экземпляр ваших сервисов (MyTaskService в этом случае) являются чрезвычайно дорогими объектами и должны использоваться как одиночные.

Это означает, что вы должны когда-либо вызывать restAdapter.create один раз и повторно использовать один и тот же экземпляр MyTaskService каждый раз, когда вам нужно взаимодействовать.

Я не могу этого достаточно подчеркнуть.

Вы можете использовать обычный шаблон singleton, чтобы гарантировать, что только один экземпляр этих объектов используется повсюду. Рамка внедрения зависимостей также была бы чем-то, что можно было бы использовать для управления этими экземплярами, но было бы чересчур избыточным, если вы еще не используете его.