Расширить все методы дополнительными параметрами, не объявляя их

1

У меня есть следующий интерфейс:

public interface HszService {

    Response<User> getUsers();

    Response<Item> getItems();

    Response<Item> getItems(ItemType type);

}

Каждый из этих методов можно вызывать в API также с параметрами int page и int pagesize.

Можно ли косвенно коснуться этих параметров выше этих параметров? Я действительно хочу избежать его определения:

public interface HszService {

    Response<User> getUsers();

    Response<User> getUsers(int page, int pagesize);

    Response<Item> getItems();

    Response<Item> getItems(int page, int pagesize);

    Response<Item> getItems(ItemType type);

    Response<Item> getItems(ItemType type, int page, int pagesize);

}

Каков наилучший образец для обработки?

Теги:

4 ответа

1
Лучший ответ

Существует несколько способов сделать это:

  1. Создайте необязательную оболочку для двух значений int PageProperties и в реализации службы, если используется значение null, верните значения по умолчанию. Интерфейс будет выглядеть так:

    public interface HszService {
        Response getUsers(PageProperties optionalPageProperties);
        Response getItems(PageProperties optionalPageProperties);
        Response getItems(ItemType type, PageProperties optionalPageProperties);
    }
  2. (Не мой любимый, чтобы сказать меньше всего...) добавить состояние к сервису:

    public interface HszService {
        void setPageProperties(int page, int pageSize);
        Response getUsers();
        Response getItems();
        Response getItems(ItemType type);
    }
  3. Вы можете заставить пользователей вводить значения и предоставлять получателям значения по умолчанию:

    public interface HszService {
        int getDefaultPage();
        int getDefaultPageSize();
        Response getUsers(int page, int pageSize);
        Response getItems(int page, int pageSize);
        Response getItems(ItemType type, int page, int pageSize);
    }

И есть много других способов. Здесь вы можете использовать всевозможные шаблоны, так как это очень простой и распространенный случай. Я не хочу рассматривать все шаблоны дизайна здесь, так как это выходит за рамки этого ответа, но вы можете найти много информации о них в Интернете.

0

Другой способ моего предыдущего ответа с помощью подхода ThreadLocal - расширить объект Response. например

public interface Response<T> {
   public List<T> getObjects();   
   public List<T> getObjects(int page, int pageSize);
}

А затем измените реализацию службы на что-то вроде этого.

public class HszServiceImpl implements HszService {

   public Response<User> getUsers(){
       return new Response<User>(){

              public List<T> getObjects(){
                  // move the old getUsers code here
              }

               public List<T> getObjects(int page, int pageSize){
                  // implement paging support
               }
       };
   }

}

Но это, возможно, будет работать только в том случае, если Response не должен быть Serializable.

0

Я считаю, что нецелесообразно передавать косвенные параметры, поскольку API косвенно. Я думаю, что вы должны расширить API с необходимыми параметрами.

Но в любом случае... вы можете использовать ThreadLocal

public interface HszService {

    public static final ThreadLocal<PagingParams> PAGING_PARAMS = new  ThreadLocal<PagingParams>();

    Response<User> getUsers();

    Response<Item> getItems();

    Response<Item> getItems(ItemType type);

}

Затем клиент может сделать что-то вроде этого

HszService.PAGING_PARAMS.set(new PagingParams(1, 10));
HszService hszService = .....; // obtain a ref somehow
hszService.getUsers();

Затем HszService должен гарантировать, что ThreadLocal потребляется (также удаляется)

public Response<User> getUsers(){
    PagingParams pageingParams = PAGING_PARAMS.get();
    PAGING_PARAMS.remove();

    ....
}

Как сказано в начале моего ответа: "API непрямой" и, следовательно, подвержен ошибкам:

  • Клиент может забыть установить ThreadLocal перед вызовом одного из методов.
  • Или потребитель параметра (например, метод getUsers) может забыть удалить ThreadLocal. Поскольку потоки часто заимствованы из пула. Тогда другой вызов может по-прежнему использовать значение ThreadLocal, которое было установлено ранее.
  • 0
    Хорошее решение, но если кто-то getItems() без установки / сброса локального потока, то он не вернет ожидаемый результат
  • 0
    Это правда, но это то, что я имею в виду под indirect API ;) Я не предпочитаю это решение, но ОП сказал, что I really want to avoid defining it .
Показать ещё 3 комментария
0

Мой комментарий сверху все еще стоит, но я просто придумал очень уродливое решение:

public interface HszService {

    Response<User> getUsers(int... pageParams);

    Response<Item> getItems(int... pageParams);

    Response<Item> getItems(ItemType type, int... pageParams);
}

Конечно, вам придется писать комментарии об этих параметрах, чтобы быть exaccty 0 или 2. Кроме того, реализация может стать уродливой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню