Философия Java


Неподдерживаемые операции - часть 2


“Что?!?” - скажете вы, удивленно. - “Все обещанные методы интерфейсов и базовых классов, делают что-либо полезное! Это нарушает обещание — это говорит о том, что вызов некоторых методов не только не обеспечит значимое поведение, но и остановит программу! Безопасный текст просто выбросит из окна!”

Это не совсем плохо. При использовании Collection, List, Set или Map, компилятор все еще ограничивает вас в вызове методов только этого интерфейса, так как это не как в Smalltalk (в котором вы можете вызвать метод для любого объекта и выйти за пределы только если вы запускаете программу, в которой ваш вызов ничего не значит). Кроме того, большинство методов, принимающий Collection в качестве аргумента только читают из Collection — все методы “чтения” для Collection не являются не обязательными.

Этот подход предотвращает крушение интерфейсов при разработке. Другие дизайны для библиотеки контейнеров всегда заканчивают запутывающим числом интерфейсов, описывающих каждый вариант главной темы, и становятся сложными в изучении. Даже невозможно собрать все возможные особые случаи для интерфейсов, потому что кто-то может всегда инвертировать новый интерфейс. Подход “неподдерживаемого действия” позволяет достигнуть важной цели библиотеки контейнеров Java: контейнеры просты в изучении; не поддерживаемые операции - особый случай, который может быть выучен позднее. Однако, для этого подхода работает:

  1. UnsupportedOperationException должно быть редким событием. То есть, для большинства классов все операции будут работать, только в редких случаях операции будут не поддерживаемыми. Это так для библиотеки контейнеров Java, так как 99% используемых вами классов — это ArrayList, LinkedList, HashSet и HashMap и их конкретные реализации — поддерживают все операции. Дизайн не поддерживает “черный ход”, если вы захотите создать новый Collection, без обеспечения значимых определений для всех методов Collection interface, и после этого добавите его к существующей библиотеке.
  2. Когда операция является не поддерживаемой, должна быть определенная вероятность появления UnsupportedOperationException во время реализации, даже после того, как вы продадите продукт покупателю. Кроме всего прочего, оно указывает на ошибку программы: вы используете реализацию неправильно. Такое случается достаточно редко в тех местах где экстремальная природа вступает в силу. Только через какое-то время мы выясним, как хорошо это работает.

В приведенном выше примере Arrays.asList( ) производит List, который основывается на массиве фиксированного размера. Поэтому, тут имеется в виду, что поддерживаются операции, которые не изменяют размер массива. С другой стороны, если новый интерфейс будет требовать выражения поведения другого рода (возможно, называемого “FixedSizeList”), это откроет дорогу сложности и вскоре вы не будете знать откуда начинать использовать библиотеку.

Документация для метода, получающего Collection, List, Set или Map в качестве аргумента, должна указывать какие дополнительные методы должны быть реализованы. Например, сортировка требует методов set( ) и Iterator.set( ), но не требует add( ) и remove( ). .




Начало  Назад  Вперед