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? подобно

  1. Список пользователей
  2. Список подрядчиков
  3. Список заданий
  4. ПОСТИТЬ новую задачу на сервер и т. Д.

Как я могу организовать код в соответствии с принципами OOP и SOLID? Это те методы, которые у меня в голове, но я не знаю, какой из них лучший.

  1. Создайте отдельные классы для всех функций Async. Согласно приведенному выше примеру у меня есть 1 интерфейс и 1 класс обработчика службы http. Таким же образом я создам 2 набора классов для каждого вызова API

  2. Создайте один интерфейсный вызов 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.

Другие вопросы по тегам