«Дизайн API похож на секс: совершите одну ошибку и поддержите ее до конца жизни» * ( Джош Блох в твиттере )
В библиотеке Java много ошибок проектирования.Stack extends Vector
( обсуждение ), и мы не можем это исправить, не вызвав поломки.Мы можем попытаться осудить Integer.getInteger
( обсуждение ), но, вероятно, это останется навсегда.
Тем не менее, некоторые виды модернизации могут быть выполнены без поломок.
Effective Java 2nd Edition, Item 18. Предпочтение интерфейсов для абстрактных классов : Существующие классы могут быть легко модифицированы для реализации нового интерфейса ".
Примеры: String implements CharSequence
, Vector implements List
и т. Д.
Effective Java 2nd Edition, Item 42: Используйте varargs разумно : Вы можете модифицировать существующий метод, который принимает массивв качестве последнего параметра он принимает varags вместо этого без влияния на существующие клиенты.
(в) известный пример - Arrays.asList
, что вызвало путаницу ( обсуждение ), но неполомка.
Этот вопрос о другом виде модернизации:
Можете ли вы модифицировать метод void
, чтобы он возвращал что-то, не нарушая существующий код?
Мои начальные догадкида, потому что:
- Тип возвращаемого значения не влияет на то, какой метод выбран во время компиляции
- Даже когдавы используете отражение, такие вещи, как
Class.getMethod
не различаются по типу возвращаемого значения
Однако я хотел бы услышать более тщательный анализ других, более опытных в Java /Дизайн API.
Приложение: Мотивация
Как указано в заголовке, одной из причин является облегчение плавного интерфейса в стиле программирования.
Рассмотрим этот простой фрагмент, который печатает перемешанный список имен:
List<String> names = Arrays.asList("Eenie", "Meenie", "Miny", "Moe");
Collections.shuffle(names);
System.out.println(names);
// prints e.g. [Miny, Moe, Meenie, Eenie]
Если бы Collections.shuffle(List)
было объявлено для возврата списка ввода, мы могли бы написать:
System.out.println(
Collections.shuffle(Arrays.asList("Eenie", "Meenie", "Miny", "Moe"))
);
В Collections
есть другие методы, которые было бы гораздо приятнее использовать, если бы они возвращали список ввода вместо void
, например, reverse(List)
, sort(List)
и т. Д. Фактически, наличие Collections.sort
и Arrays.sort
return void
является особеннымПрискорбно, потому что это лишает нас возможности писать выразительный код, такой как этот:
// DOES NOT COMPILE!!!
// unless Arrays.sort is retrofitted to return the input array
static boolean isAnagram(String s1, String s2) {
return Arrays.equals(
Arrays.sort(s1.toCharArray()),
Arrays.sort(s2.toCharArray())
);
}
Этот тип возврата void
, предотвращающий беглость, конечно, не ограничивается только этими служебными методами.Методы java.util.BitSet
также могли бы быть написаны так, чтобы они возвращали this
(ala StringBuffer
и StringBuilder
) для облегчения беглости.
// we can write this:
StringBuilder sb = new StringBuilder();
sb.append("this");
sb.append("that");
sb.insert(4, " & ");
System.out.println(sb); // this & that
// but we also have the option to write this:
System.out.println(
new StringBuilder()
.append("this")
.append("that")
.insert(4, " & ")
); // this & that
// we can write this:
BitSet bs1 = new BitSet();
bs1.set(1);
bs1.set(3);
BitSet bs2 = new BitSet();
bs2.flip(5, 8);
bs1.or(bs2);
System.out.println(bs1); // {1, 3, 5, 6, 7}
// but we can't write like this!
// System.out.println(
// new BitSet().set(1).set(3).or(
// new BitSet().flip(5, 8)
// )
// );
К сожалению, в отличие от StringBuilder
/ StringBuffer
, ALL из мутаторов BitSet
возвращают void
.
Похожие темы