Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Мизрохи С.В. -> "Turbo Pascal и объектно-ориентированное программирование" -> 36

Turbo Pascal и объектно-ориентированное программирование - Мизрохи С.В.

Мизрохи С.В. Turbo Pascal и объектно-ориентированное программирование — М.: Финансы и статистика , 1992. — 192 c.
ISBN 5-279-00903-2
Скачать (прямая ссылка): efektispolzc2000.djvu
Предыдущая << 1 .. 30 31 32 33 34 35 < 36 > 37 38 39 40 41 42 .. 105 >> Следующая

Попробуйте подойти к этому так: поставьте перед собой задачу построения класса, который был бы полным и минимальным.
Полный интерфейс дает возможность пользователю в некоторых пределах делать все, что ему хочется. То есть для любой разумной задачи, которую пользователь желает решить, должен существовать реальный способ достижения поставленной цели, хотя он может и не быть столь удобным, как хотелось бы. С другой стороны, минимальный интерфейс - это интерфейс с минимально возможным количеством функций, таким, что никакие две функции интерфейса не обладают перекрывающейся функциональностью. Если вы предлагаете полный минимальный интерфейс, пользователи могут делать все, что им заблагорассудится, но интерфейс класса не должен быть более сложным, чем это в принципе необходимо.
Стремление к полному интерфейсу кажется достаточно разумным, но зачем нужна минимальность? Почему просто не дать пользователю все, что он хочет, совершенствуя функциональность до тех пор, пока все не будут удовлетворены?
Помимо морального аспекта (насколько это правильно - баловать пользователей?) у интерфейса класса, перегруженного функциями, существуют и технические недостатки. Во-первых, чем больше функций в интерфейсе, тем труднее его понять потенциальному клиенту, и, соответственно, с тем большей неохотой он будет обучаться использованию такого интерфейса. Класс с десятью функциями кажется посильным большинству пользователей; класс со ста функциями у большинства программистов, как правило, вызывает желание никогда больше его не видеть. Расширяя Функциональность так, чтобы сделать класс как можно более привлекательным, вы в действительности можете добиться того, что отобьете охоту к его изучению.
Перегруженный интерфейс может даже привести к путанице. Предположим, что вы создаете класс, который поддерживает мышление для системы искусственного интеллекта. Одна из функций-членов называется think (думать), но позднее вы обнаруживаете, что некоторым хотелось бы иметь функцию, называемую ponder (раздумывать), другие же предпочитают название ruminate (размышлять). Пытаясь понравиться всем, вы предлагаете все три функции, хотя они делают одно и то же. Подумайте, в каком состоянии оказывается пользователь, столкнувшийся с тремя Различными функциями, которые должны играть одну роль. Он наверняка задумайся, на самом ли деле это так? Нет ли между тремя функциями некоторых малозаметных различий, возможно в эффективности или надежности? Если нет, то почему их три? Вместо того чтобы оценить вашу гибкость, потенциальный пользователь будет теряться в догадках, о чем вы думали (или раздумывали, или размышляли), Поступая таким образом.
Второй недостаток перегруженных интерфейсов классов — трудности в эксплуа-ии. Действительно, класс со многими функциями намного труднее поддерживать
Классы и функции
и совершенствовать, чем класс, содержащий лишь несколько функций. Намного сложнее избегать дублирования кода (и сопутствующего дублирования ошибок), равно как и оставаться последовательным в интерфейсе. Такой класс также гораздо труднее документировать.
И наконец, перегруженные определения классов приводят к использованию длинных файлов заголовков. Поскольку файлы заголовков обычно необходимо читать всякий раз при компиляции программы (см. правило 34), определения классов, раздутые сверх меры, вызывают значительное увеличение времени компиляции.
Короче говоря, непродуманное добавление функций к интерфейсу обходится дорого, поэтому следует хорошо подумать, оправдано ли дополнительное удобство, обеспечиваемое несколькими функциями (если интерфейс полон, новые функции добавляются только ради удобства).
Нередко создание более чем минимального набора функций вполне оправданно. Если часто выполняемая задача может быть реализована намного более эффективно как функция-член, это вполне достойный повод для добавлений к интерфейсу. Если добавление функции-члена делает класс значительно более удобным в использовании, этого может быть достаточно для включения в класс. И, если добавление функции может помочь предотвратить ошибки пользователя, это также должно служить весомым аргументом в пользу ее включения в интерфейс класса.
Давайте рассмотрим конкретный пример: шаблон класса, реализующий массив с задаваемой пользователем верхней и нижней границей и предлагающий факультативную проверку на выход за границы индекса. Первые шаги к созданию такого шаблона массива выглядят так:
template<class Т> class Array { public:
enum BoundsCheckingStatus {NO_CHECK_BOUNDS = 0, CHECK JBOUNDS = 1}; Array(int lowBound, int highBound,
BoundsCheckingStatus check = NO_CHECK_BOUNDS); Array (const Arrays rhs) ; -Array ();
Arrays operator=(const Arrays rhs) ; private:
int lBound, hBound; Il Нижняя и верхняя границы. vector<T> data; Il Содержимое массива; информацию
// о vector см. в правиле 49. BoundsCheckingStatus checkingBounds;
};
Функции-члены, объявленные до сих пор, практически не вызывают вопросов. У вас имеется конструктор, позволяющий пользователю задавать границы массива, конструктор копирования, оператор присваивания и деструктор. В данном случае вы объявляете функции как невиртуальные, подразумевая, что класс не будет использоваться в качестве базового (см. правило 14).
Предыдущая << 1 .. 30 31 32 33 34 35 < 36 > 37 38 39 40 41 42 .. 105 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100