Есть ли способ повторно использовать код строителя для переоснащения
Я использую 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);
}
// ...
}
Что такое хороший способ сделать этот код СУХОЙ?
Ответы
Ответ 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, чтобы гарантировать, что только один экземпляр этих объектов используется повсюду. Рамка внедрения зависимостей также была бы чем-то, что можно было бы использовать для управления этими экземплярами, но было бы чересчур избыточным, если вы еще не используете его.