У одного из моих классов есть поле, которое содержит Набор. Это поле заполняется только в конструкторе, а затем читается другими классами. Изначально у меня было что-то вроде этого:
public class Foo {
public final Set<String> myItems;
public Foo(Collection<String> theirItems) {
this.myItems = new LinkedHashSet<String>(theirItems);
}
}
Но это идет вразрез с передовой практикой ОО, согласно которой myItems должен быть закрытым и доступным только через сеттеры и геттеры. Итак, я изменил его на:
public class Foo {
private final Set<String> myItems;
public Foo(Collection<String> theirItems) {
this.myItems = new LinkedHashSet<String>(theirItems);
}
public Set<String> getItems() {
return myItems;
}
}
Теперь myItems является приватным, но тот, кто вызывает getItems (), может добавлять / удалять элементы по своему желанию, что по сути та же ситуация, что и раньше. (На самом деле я не беспокоюсь о том, чтобы кто-то изменил содержимое предмета, это скорее теоретический вопрос)
Итак, я изменил getItems (), чтобы он возвращал массив:
public String[] getItems() {
return myItems.toArray(new String[myItems.size()]);
}
Теперь мои вещи действительно закрыты. К сожалению, я знаю, что объект, который будет читать элементы, на самом деле захочет работать с множеством, поэтому ему придется конвертировать массив обратно. Я также мог бы вернуть копию myItems:
public Set<String> getItems() {
return new LinkedHashSet<String>(myItems);
}
Это дает звонящему то, что он хочет, но создает новый Набор при каждом доступе.
Что вы делаете в подобной ситуации - сохранить конфиденциальность любой ценой и принять преобразование / копирование исходной структуры или пожертвовать контролем над содержимым коллекции и полагаться на ответственных абонентов?