Главная » Java, Советы » Тщательно проектируйте сигнатуру метода

0

 

В этой статье приводятся советы по проектированию API, не удостоившиеся собственной статьи. Собранные вместе, они помогут сделать ваш АРI не dтоль подверженным ошибкам, более удобным и простым в изучении.

 

 

Тщательно выбирайте названия методов. Названия всегда должны соответствовать стандартным соглашениям по именованию (статья 38). Вашей главной целью должен быть выбор таких имен, которые будут понятны и согласуются с остальными названиями в том же пакете. Второй целью должен быть выбор имен, отвечающих более общим соглашениям, если таковые имеются. В случае сомнений смотрите руководство по API библиотек языка Jаvа. Несмотря на массу противоречий’, которые неизбежны если учитывать размер и возможности библиотек, здесь также существует консенсус. Бесценным источником является "The Java Developers Almaпac" Патрика Чана (Patrick Chan) [ChanOO], содержащий декларации всех без исключения методов в библиотеках платформы Jаvа, индексированные в алфавитном порядке, если, к примеру, вы сомневаетесь, назвать ли метод remove или delete, то, бегло про смотрев указатель в этой книге, поймете, что, без всяких сомнений, выбор remove лучше: есть сотни методов, чьи названия начинаются со слова remove, и лишь жалкая горстка имен, которые начинаются со слова delete.

Не заходите слишком далеко в погоне за удобством своих методов. Каждый метод должен выполнять собственную часть работы. Избыток методов делает класс сложным для изучения, использования, описания, тестирования и сопровождения. В отношении интерфейсов это верно вдвойне: большое количество методов усложняет жизнь и разработчикам, и пользовате,лям. для каждого действия, поддерживаемого вашим типом, создайте полнофункциональный метод. Сокращенный вариант операции рассматривайте лищь в том случае, если он будет использоваться часто. Если есть сомнения, забудьте об этом варианте.

Избегайте длинного перечня параметров. Правило таково, что на практике три параметра нужно рассматривать как максимум, и чем параметров меньше, тем лучше. Большинство программистов не способны помнить более длинные списки параметров. Если целый ряд методов превышает этот предел, вашим API невозможно будет пользоваться, не обращаясь беспрестанно к его описанию. Особенно вредны длинные последовательности параметров одного и того же типа. И это не только потому, что ваш пользователь не сможет запомнить порядок их следования. Если он по ошибке поменяет их местами, его программа все равно будет компилироваться и работать. Только вот делать она будет совсем не то, что хотел ее автор.

для сокращения слишком длинных списков параметров можно использовать два приема. Первый заключается в разбиении метода на несколько методов, каждому ИЗ которых нужно лишь какое-то подмножество его параметров. Если делать это неаккуратно, может получиться слишком много методов, однако этот же прием помогает сократить количество методов путем увеличения их ортогональности. Например, рассмотрим интерфейс java.util.List. У него нет методов для поиска индекса первого и последнего элемента в подсписке, каждому из них потребовалось бы по три параметра. Вместо этого он предлагает метод subList, который принимает два параметра И возвращает представление подсписка. Для получения желаемого результата можно объединить метод subList с методами indexOf и lastlndexOf, принимающими по одному параметру. Более того, метод subList можно сочетать с любыми другими Методами экземпляра List, чтобы выполнять самые разные операции для подсписков. Полученный АРI имеет высокое соотношение мощности и размера.

 

Второй прием сокращения чрезмерно длинных перечней параметров заключается в создании вспомогательных классов, обеспечивающих агрегирование параметров. Обычно эти вспомогательные классы являются статическими классами-членами (статья 18). Данный прием рекомендуется использовать, когда становится понятно, что часто возникающая последовательность параметров на самом деле представляет некую отдельную сущность. Предположим, что вы пишите класс, реализующий карточную игру, и выясняется, что постоянно передается последовательность из двух параметров: достоинство карты и ее масть. И ваш АРI и содержимое вашего класса, вероятно, выиграют, если для представления карты вы создадите вспомогательный класс и каждую такую последовательность параметров замените одним параметром, соответствующим этому вспомогательному классу.

Выбирая тип параметра, отдавайте предпочтение интерфейсу, а не классу. Если для декларации параметра имеется подходящий интерфейс, всегда используйте его, а не класс, который реализует этот интерфейс. Например, нет причин писать метод, принимающий параметр типа Hashtable, лучше использовать Мар. Это позволит вам передавать этому методу Hashtable, HashMap, ТгееМар, подмножество ТгееМар, и вообще любую, пока еще не написанную реализацию интерфейса Мар. Применяя же вместо интерфейса класс, вы навязываете вашему клиенту конкретную реализацию и вынуждаете выполнять ненужное и потенциально трудоемкое копирование в том случае, если входные данные будут представлены в какой-либо иной форме.

Объекты-функции (статья 22) применяйте с осторожностью. Некоторые языки, в частности Smalltalk и различные диалекты Lisp, поощряют стиль программирования, изобилующий объектами, представляющими функции, которые можно применять к другим объектам. Программисты, имеющие опыт работы с такими языками, могут поддаться соблазну и использовать тот же стиль для Java, но это не слишком хороший выбор. Проще всего создавать объект-функцию с помощью анонимного класса (статья 18), однако даже это приводит к некоторому загромождению синтаксиса и ограничивает мощность и производительность в сравнении со встроенными управляющими конструкциями (inline control construct). Более того, стиль программирования, когда вы постоянно создаете объекты-функции и передаете их из одного метода в другой, расходится с господствующей тенденцией, а потому, если вы будете придерживаться этого стиля, другим программистам будет трудно разобраться в вашем коде. Это не означает, что объекты-функции не имеют права на использование. Напротив, они важны для многих мощных шаблонов, таких как Strategy [Саmmа95, стр. 315] и Visitor [Саmmа95, стр. 331]. Точнее говоря, объекты-функции следует применять только при наличии веских причин.

 

Источник: Джошуа Блох, Java TM Эффективное программирование, Издательство «Лори»

По теме:

  • Комментарии