Android - Отделите асинхронный http-код от действия в соответствии с принципами SOLID.
Я хочу отделить асинхронный http-код от действий, поскольку я повторно использую код. Вот чем я сейчас занимаюсь:
Я хочу получить список проектов из REST API и сохранить его в массиве. (Предположим, я не использую локальное кэширование, так как хочу загружать их каждый раз)
ProjectInterface.java
public interface ProjectInterface {
public void onProjectsLoaded(ArrayList<Project> projectArrayList);
}
HttpProjectList.java
//async class will get the results from the server and send to the activity
public class HttpProjectList {
protected ProjectInterface interface;
protected Context c;
public HttpProjectList(ProjectInterface interface, Context c){
this.interface = interface;
this.c = c;
}
//Run Async task Volley here
public void projectListRequest() {
RequestQueue requestQueue = Volley.newRequestQueue(this.c);
JsonArrayRequest req = new JsonArrayRequest(Path.WORK_ORDERS, success, error);
requestQueue.add(req);
}
//on success set the data
private Response.Listener<JSONArray> success = new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
//do dome parsing here and populate the array
interface.onProjectsLoaded(projectArrayList);
}
}
//error function here, i'm not typing
}
MyActivity.java
//I'm calling all in this activity
public class BaseActivity extends Activity implements ProjectInterface {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(setView());
HttpProjectList httpList = new HttpProjectList(this, getBaseContext());
httpList.projectListRequest(); //fire http call
}
//run after projects loaded
@Override
public void onProjectsLoaded(ArrayList<Project> projectArrayList) {
//Do something with the server data
}
}
В этом случае у меня есть один API, который заполняет массив. Что делать, если у меня несколько вызовов API? подобно
- Список пользователей
- Список подрядчиков
- Список заданий
- ПОСТИТЬ новую задачу на сервер и т. Д.
Как я могу организовать код в соответствии с принципами OOP и SOLID? Это те методы, которые у меня в голове, но я не знаю, какой из них лучший.
Создайте отдельные классы для всех функций Async. Согласно приведенному выше примеру у меня есть 1 интерфейс и 1 класс обработчика службы http. Таким же образом я создам 2 набора классов для каждого вызова API
Создайте один интерфейсный вызов HttpInterface и поместите в него все функции обратного вызова, а также создайте другой класс HttpHandler и поместите все методы http всех вызовов API.
Какой из них лучше? Или есть другой способ? Можете ли вы дать совет по этому поводу? Большое спасибо!
1 ответ
Оба предложенных вами подхода следуют шаблону Observer. Я бы лично предложил второй подход, где все методы заключены в одном интерфейсе. Однако, если число методов возрастает (скажем, выше 5), то, возможно, вам нужно подумать о том, чтобы сгруппировать их таким образом, чтобы это отражало функциональность объекта. Например, вы можете иметь:
public interface HttpUserListener {
public void onUserListReceived(List<User> users);
public void onUserAdd(User user);
public void onUserRemove(User user);
}
public interface HttpProjectListener {
public void onProjectListReceived(List<Project> projects);
public void onProjectAssigned(Project project, User user);
public void onProjectComplete(Project project);
}
В части реализации, вероятно, вам нужен список слушателей, которые будут вызываться для определенного события:
public class HttpHandler {
protected List<HttpUserListener> userListeners;
protected List<HttpProjectListener> projectListeners;
protected Context c;
public HttpHandler(Context c){
this.c = c;
}
public void registerListener(UserListener listener){
if(userListeners == null){
userListeners = new ArrayList<UserListener>(1);
}
userListener.add(listener);
}
public void unregisterListener(UserListener listener){
if(userListeners == null){
return;
}
userListener.remove(listener);
}
public void asyncAddUser(User user){
// provide the async method and call the listeners
if(userListeners != null)
for(UserListener l: userListeners)
l.onUserAdd(user);
}
}
Хочу подчеркнуть, что идеальным местом создания и обработки асинхронных задач в Android являются Сервисы. Итак HttpHandler
будет продлен Service
(или же IntentService
который уже предоставляет рабочий поток), и вы можете регистрировать и отменять регистрацию слушателей этой службы, используя подход привязки. Это хороший учебник с сайта разработчиков Android.
В качестве альтернативы вы можете забыть о традиционном подходе слушателя и иметь единый сервис, который будет передавать намерения, когда происходит HTTP-вызов. И пусть ваши действия фиксируют эти трансляции и реагируют соответственно. Это ближе к архитектуре программирования Android.