Чтение онлайн

ЖАНРЫ

Технологии программирования

Костерин В В

Шрифт:

Классы из предметной (прикладной) области — непосредственно отражают понятия из прикладной области, т. е. понятия, которые использует конечный пользователь для описаний своих задач и методов их решения.

Лучшее средство для поиска этих понятий/классов — грифельная доска, а лучший метод первого уточнения — беседа со специалистами в области приложения или просто с друзьями. Обсуждение необходимо, чтобы создать начальный словарь терминов и понятийную структуру.

Главное в хорошем проекте — прямо отразить какое-либо понятие "реальности", т. е.

уловить понятие из области приложения классов, представить взаимосвязь между классами строго определенным способом, например с помощью наследования, и повторить эти действия на разных уровнях абстракции.

Классы, являющиеся артефактами реализации или абстракциями периода реализации, — это те понятия, которые применяют программисты и проектировщики для описания методов реализации:

• классы, отражающие ресурсы оборудования (оперативная память, механизмы управления ресурсами, дисковое пространство);

• классы, представляющие системные ресурсы (процессы, потоки ввода-вывода);

• классы, реализующие программные структуры (стеки, очереди, списки, деревья, словари и т. п.);

• другие абстракции, например элементы управления программой (кнопки, меню и т. п.).

Хорошо спроектированная система должна содержать классы, которые дают возможность рассматривать систему с логически разных точек зрения.

Пример:

1) классы, представляющие пользовательские понятия (например, легковые машины и грузовики);

2) классы, представляющие обобщения пользовательских понятий (движущиеся средства);

3) классы, представляющие аппаратные ресурсы (например, класс управления памятью);

4) классы, представляющие системные ресурсы (например, выходные потоки);

5) классы, используемые для реализации других классов (например, списки, очереди);

6) встроенные типы данных и структуры управления.

В больших системах очень трудно сохранять логическое разделение типов различных классов и поддерживать такое разделение между различными уровнями абстракции. В приведенном выше перечислении представлены три уровня абстракции:

(1+2) — представляет пользовательское отражение системы;

(3+4) — представляет машину, на которой будет работать система;

(5+6) — представляет низкоуровневое (со стороны языка программирования) отражение реализации.

Чем больше система, тем большее число уровней абстракции необходимо для ее описания и тем труднее определять и поддерживать эти уровни абстракции. Отметим, что таким уровням абстракции есть прямое соответствие в природе и в различных построениях человеческого интеллекта. Например, можно рассматривать дом как объект, состоящий из атомов; молекул; досок и кирпичей; стен, пола и потолков; комнат.

Пока удается хранить раздельно представления этих уровней абстракции, можно поддерживать целостное представление о доме. Однако если смешать их, возникнет бессмыслица.

Взаимоотношения, о которых мы говорим, естественно устанавливаются в области приложения или (в случае повторных проходов по шагам проектирования) возникают из последующей работы над структурой классов. Они отражают наше понимание основ области приложения и часто являются классификацией основных понятий. Пример такого отношения —

машина с выдвижной лестницей есть грузовик, есть пожарная машина, есть движущееся средство.

8.8.3. Шаг 2. Уточнение классов с определением набора операций (методов) для каждого

В действительности нельзя разделить процессы определения классов и выяснения того, какие операции для них нужны. Однако на практике они различаются, поскольку при определении классов внимание концентрируется на основных понятиях, не останавливаясь на программистских вопросах их реализации, тогда как при определении операций прежде всего сосредоточиваются на том, чтобы задать полный и удобный набор операций. Часто бывает слишком трудно совместить оба подхода, в особенности, учитывая, что связанные классы надо проектировать одновременно.

Возможно несколько подходов к процессу определения набора операций. Предлагаем следующую стратегию:

— рассмотрите, каким образом объект класса будет создаваться, копироваться (если нужно) и уничтожаться;

— определите минимальный набор операций, необходимый для понятия, представленного классом;

— рассмотрите операции, которые могут быть добавлены для удобства записи, и включите только несколько действительно важных;

— рассмотрите, какие операции можно считать тривиальными, т. е. такими, для которых класс выступает в роли интерфейса для реализации производного класса;

— рассмотрите, какой общности именования и функциональности можно достигнуть для всех классов компонента.

Очевидно, что это стратегия минимализма. Гораздо проще добавить любую функцию, приносящую ощутимую пользу, и сделать все операции виртуальными. Но чем больше функций, тем больше вероятность, что они не будут использоваться, наложат определенные ограничения на реализацию и затруднят эволюцию системы. Гораздо легче включить в интерфейс еще одну функцию, как только установлена потребность в ней, чем удалить ее оттуда, когда уже она стала привычной.

Причина, по которой мы требуем явного принятия решения о виртуальности данной функции, не оставляя его на стадию реализации, в том, что, объявив функцию виртуальной, существенно повлияем на использование ее класса и на взаимоотношения этого класса с другими.

При определении набора операций (методов) больше внимания следует уделять тому, что надо сделать, а не тому, как это сделать.

Иногда полезно классифицировать операции класса по тому, как они работают с внутренним состоянием объектов:

1) базовые операции: конструкторы, деструкторы, операции копирования;

2) селекторы: операции, не изменяющие состояния объекта;

3) модификаторы: операции, изменяющие состояние объекта;

4) операции преобразований, т. е. операции, порождающие объект другого типа, исходя из значения (состояния) объекта, к которому они применяются;

5) повторители: операции, которые открывают доступ к объектам класса или используют последовательность объектов.

Кроме уже перечисленных групп методов, в классы могут быть введены дополнительные методы самотестирования и проверки корректности данных. Это не есть разбиение на ортогональные группы операций. Например, повторитель может быть спроектирован как селектор или модификатор.

Поделиться с друзьями: