Мои Конспекты
Главная | Обратная связь


Автомобили
Астрономия
Биология
География
Дом и сад
Другие языки
Другое
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Металлургия
Механика
Образование
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Туризм
Физика
Философия
Финансы
Химия
Черчение
Экология
Экономика
Электроника

Тщательно проектируйте сигнатуру метода



В этой статье приводятся советы по проектированию 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]. Точнее говоря, объекты-функции следует применять только при наличии веских причин.