У меня есть следующий интерфейс:
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);
}
Каков наилучший образец для обработки?
Существует несколько способов сделать это:
Создайте необязательную оболочку для двух значений int PageProperties и в реализации службы, если используется значение null, верните значения по умолчанию. Интерфейс будет выглядеть так:
public interface HszService {
Response getUsers(PageProperties optionalPageProperties);
Response getItems(PageProperties optionalPageProperties);
Response getItems(ItemType type, PageProperties optionalPageProperties);
}
(Не мой любимый, чтобы сказать меньше всего...) добавить состояние к сервису:
public interface HszService {
void setPageProperties(int page, int pageSize);
Response getUsers();
Response getItems();
Response getItems(ItemType type);
}
Вы можете заставить пользователей вводить значения и предоставлять получателям значения по умолчанию:
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);
}
И есть много других способов. Здесь вы можете использовать всевозможные шаблоны, так как это очень простой и распространенный случай. Я не хочу рассматривать все шаблоны дизайна здесь, так как это выходит за рамки этого ответа, но вы можете найти много информации о них в Интернете.
Другой способ моего предыдущего ответа с помощью подхода 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
.
Я считаю, что нецелесообразно передавать косвенные параметры, поскольку 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
перед вызовом одного из методов.ThreadLocal
. Поскольку потоки часто заимствованы из пула. Тогда другой вызов может по-прежнему использовать значение ThreadLocal
, которое было установлено ранее.Мой комментарий сверху все еще стоит, но я просто придумал очень уродливое решение:
public interface HszService {
Response<User> getUsers(int... pageParams);
Response<Item> getItems(int... pageParams);
Response<Item> getItems(ItemType type, int... pageParams);
}
Конечно, вам придется писать комментарии об этих параметрах, чтобы быть exaccty 0 или 2. Кроме того, реализация может стать уродливой.
getItems()
без установки / сброса локального потока, то он не вернет ожидаемый результатindirect API
;) Я не предпочитаю это решение, но ОП сказал, чтоI really want to avoid defining it
.