У вас есть два варианта:
Решение # 1 Создать метод, как вы сказали. Это будет считаться статическим заводским методом . Хотя он похож на конструктор, он позволяет указать идентификатор (имя). Хотя, если имя не является проблемой, статические заводские методы могут быть чрезмерно сложными; вы можете просто передать список и ввести его в конструктор. Ниже приведен пример статического заводского метода; используя конструктор потребует конструктор быть не частный:
class Query {
private List<Filter> filters;
private String type;
private Query(String type, List<Filter> filters) {
}
public static Query buildWithFilters(String type, List<Filter> filters) {
return new Query(type, filters);
}
}
Вы бы тогда назвать это нравится:
List<Filter> filters = new ArrayList<>();
//add filters
Query query = Query.buildWithFilters("type", filters);
Решение # 2 Builder pattern позволяет установить факультативным и обязательным состояние объекта перед его созданием. После строительства объект может оставаться неизменным.
class Query {
private final String type;
private final List<Filter> filters;
private Query(Builder b) {
type = b.type;
type = b.filters;
}
private static final class Builder {
private String type;
private List<Filter> filters;
public Builder(String type) {
this.type = type;
}
public Builder addFilter(Filter filter) {
if(filters == null)
filters = new ArrayList<>();
filters.add(filter);
}
public Query build() {
return new Query(this);
}
}
}
Вы можете построить свой объект, как это:
Query query = new Query.Builder("type").addFilter(filter1).build();
Хитрость здесь хранит состояние в Builder
случае перед передачей его к экземпляру, который вы пытаетесь создать.Это позволяет вам сначала указать свойства перед созданием объекта, а затем построить объект с этими свойствами через метод builder'a build()
.
Если вы не можете изменить Query
класса, ваш следующий вариант будет создание непреложной обертки:
final class QueryWrapper {
private final Query query;
private final List<Filter> filters;
private QueryWrapper(Builder b) {
query = b.query;
filters = b.filters;
}
public static final class Builder {
private Query query;
private List<Filter> filters;
public Builder(Query query) {
this.query = query;
}
public Builder addFilter(Filter filter) {
if(filters == null)
filters = new ArrayList<>();
filters.add(filter);
}
public QueryWrapper build() {
new QueryWrapper(this);
}
}
}
Оболочка позволяет инкапсулировать экземпляр Query
. Затем клиенты связывают с оберткой Query
; оболочка управляет изменчивостью.
Строитель позволяет по желанию добавлять фильтры, если хотите. Обертка неизменна, поэтому мы хотим указать дополнительные фильтры перед созданием обертки. Конструктор строителя заставляет клиента проходить в экземпляре Query
(каждая обертка должна иметь Query
).
Похоже, вы можете назвать 'setFilter' на него столько раз, сколько вы хотите; что мешает вам перебирать фильтры и делать это? –
Посмотрите на рисунок Строителя –
Не могли бы вы объяснить более подробно. Похоже, вы можете просто называть setFilter for-loop на каждой итерации, но вы хотите что-то еще, не так ли? – dbf