Узнайте, как выбрать правильные типы параметров метода и получить более надежный и короткий код в своих Java-приложениях.
У нас, Java-разработчиков, обычно есть плохая привычка использовать параметры методов, не думая о том, что на самом деле нужно, и просто выбирая то, к чему мы привыкли, что у нас есть или все, что приходит на ум. Рассмотрим следующий типичный пример:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private static String poem(Map<Integer, String> numberToWord) { return new StringBuilder() .append( "There can be only " ) .append(numberToWord.get( 1 )) .append( " of you.\n" ) .append( "Harts are better of when there are " ) .append(numberToWord.get( 2 )) .append( " of them together.\n" ) .append( "These " ) .append(numberToWord.get( 3 )) .append( " red roses are a symbol of my love to you.\n" ) .toString(); } |
Когда мы используем метод выше, мы предоставляем карту, которая переводит из числа в строку. Мы могли бы, например, предоставить следующую карту:
1
2
3
4
|
Map<Integer, String> englishMap = new HashMap<>(); englishMap.put( 1 , "one" ); englishMap.put( 2 , "two" ); englishMap.put( 3 , "three" ); |
Когда мы вызываем наш метод poem с помощью englishMap, метод выдаст следующий результат:
1
2
3
|
There can be only one of you. Harts are better of when there are two of them together. These three red roses are a symbol of my love to you. |
Это звучит неплохо. Теперь предположим, что ваш главный друг — компьютерный ботаник, и вы хотите оживить свое стихотворение и произвести впечатление, тогда вот путь:
1
2
3
4
|
Map<Integer, String> nerdMap = new HashMap<>(); nerdMap.put( 1 , "1" ); nerdMap.put( 2 , "10" ); nerdMap.put( 3 , "11" ); |
Если мы сейчас передадим наш nerdMap методу poem, он выдаст следующее стихотворение:
1
2
3
|
There can be only 1 of you. Harts are better of when there are 10 of them together. These 11 red roses are a symbol of my love to you. |
Как и во всех стихах, трудно судить, какое стихотворение является более романтичным, чем другое, но у меня, конечно, есть свое личное мнение.
Проблемы
Есть несколько проблем с решением выше:
Прежде всего, мы не можем быть уверены, что метод poem не изменит предоставляемую нами карту. В конце концов, мы предоставляем карту, и ничто не мешает получателю делать с картой все возможное, даже полностью очищая карту. Этого, конечно, можно избежать, обернув карту с помощью метода Collections.unmodifiableMap () или предоставив копию существующей карты, в результате чего копия впоследствии будет отброшена.
Во-вторых, мы привязаны к использованию карты, когда нам нужно только то, что переводится из целого числа в строку. Это может создать ненужный код в некоторых случаях. Вспомните наш nerdMap, где значения в карте можно легко вычислить, используя Integer :: toBinaryString, а не отображать их вручную.
Решение
Мы должны стремиться предоставить именно то, что нужно в той или иной ситуации, а не больше. В нашем примере мы должны изменить метод poem, чтобы получить функцию, которая переходит от целого числа к строке. То, как эта функция реализована на стороне вызывающей стороны, имеет меньшее значение, это может быть карта или функция, или код или что-то еще. Вот как это должно быть сделано в первую очередь:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private static String poem(IntFunction<String> numberToWord) { return new StringBuilder() .append( "There can be only " ) .append(numberToWord.apply( 1 )) .append( " of you.\n" ) .append( "Harts are better of when there are " ) .append(numberToWord.apply( 2 )) .append( " of them together.\n" ) .append( "These " ) .append(numberToWord.apply( 3 )) .append( " red roses are a symbol of my love to you.\n" ) .toString(); } |
Если мы хотим использовать метод poem с Map, мы просто вызываем его так:
1
2
|
// Expose only the Map::get method System.out.println(poem(englishMap::get)); |
1
|
|
Если мы хотим вычислить значения, которые мы сделали для стихотворения ботаника, мы можем сделать это еще проще:
1
|
System.out.println(poem(Integer::toBinaryString)); |
Черт возьми, мы можем даже написать стихотворение для значительного другого страдающего от двойственного расстройства личности, такого как это:
1
2
3
4
5
|
System.out.println( poem( no -> englishMap.getOrDefault(no + 1 , Integer.toString(no + 1 )) ) ); |
Это произведет следующее стихотворение:
1
2
3
|
There can be only two of you. Harts are better of when there are three of them together. These 4 red roses are a symbol of my love to you. |
Будьте осторожны с параметрами вашего метода!
Ссылка: | Используйте точные параметры метода Java от нашего партнера JCG Пера Минборга из блога Minborg по Java Pot . |