Костерин В В
Шрифт:
1) базовые операции: конструкторы, деструкторы, операции копирования;
2) селекторы: операции, не изменяющие состояния объекта;
3) модификаторы: операции, изменяющие состояние объекта;
4) операции преобразований, т. е. операции, порождающие объект другого типа, исходя из значения (состояния) объекта, к которому они применяются;
5) повторители: операции, которые открывают доступ к объектам класса или используют последовательность объектов.
Кроме уже перечисленных групп методов, в классы могут быть введены дополнительные методы самотестирования и проверки корректности данных. Это не есть разбиение на ортогональные группы операций. Например, повторитель может быть спроектирован как селектор или модификатор.
Выделение этих групп просто предназначено помочь в процессе проектирования интерфейса класса. Конечно, допустима и другая классификация.
Виды взаимоотношений между классами могут быть следующими: отношения наследования; отношения включения; отношения использования; запрограммированные отношения.
Еще одно взаимоотношение — отношение включения {агрегирования) — класс содержит в виде члена объект или указатель на объект другого класса. Позволяя объектам содержать указатели на другие объекты, можно создавать так называемые "иерархии объектов". Такие реализации альтернативно дополняют возможности использования иерархии классов.
Очень важным при проектировании является вопрос: какое отношение выбрать — агрегации (включения) или наследования. В принципе эти методы взаимозаменяемы, кроме случая, когда используется позднее связывание. Наиболее предпочтителен тот вариант, в котором наиболее точно моделируется окружающая действительность, т. е. если понятие X является частью понятия Y, то используется включение. Если понятие X более общее, чем Y, — то наследование.
Для составления и понимания проекта часто необходимо знать, какие классы и каким способом они используются, другими словами, отношения использования. Возможно следующим образом классифицировать те способы, с помощью которых класс X может использовать класс Y.
— X использует Y;
— X вызывает функцию-член (метод) Y;
— X читает член Y;
— X пишет в член Y;
— X создает Y;
— X размещает переменную из Y
Анализ подобных взаимосвязей позволяет выявить потребности в определенных методах классов или, наоборот, выявить их ненужность.
Запрограммированные отношения — те отношения проекта, которые не могут быть прямо представлены в виде конструкций языка. Допустим, в проекте оговорено, что каждая операция, не реализованная в классе А, должна обслуживаться объектом класса В. К запрограммированным отношениям относят также операции преобразования типов. Следует, по возможности, избегать применения этого вида отношений из-за усложнения реализации. Идеальный класс должен в минимальной степени зависеть от остального мира. Следовательно, следует стараться минимизировать зависимости.
Спрячем подробности реализации за фасадом интерфейса. Объект инкапсулирует поведение, если он умеет выполнять некоторые действия, но подробности, как это делается, остаются скрытыми за фасадом интерфейса. Эта идея была сформулирована специалистом по информатике Дэвидом Парнасом в виде правил, которые часто называются принципами Парнаса.
Правило 1. Разработчик программы должен предоставлять пользователю всю информацию, которая нужна для эффективного использования приложения, и ничего кроме этого.
Правило 2. Разработчик программного обеспечения должен знать только требуемое поведение объекта и ничего кроме этого.
Следствие принципа отделения интерфейса от реализации состоит в том, что программист может экспериментировать с различными алгоритмами, не затрагивая остальные классы объектов программы.
На этом шаге дается четкое описание классов, их данных и методов (опуская реализацию и, возможно, скрытые методы). Всем методам задаются точные типы параметров.
Идеальный интерфейс представляет пользователю полный и последовательный набор понятий; согласован со всеми частями компоненты; не открывает подробности реализации и может быть реализован различными способами; ограниченно и четко определенным образом зависит от других интерфейсов.
Интерфейсы классов предоставляют полную информацию для реализации классов на этапе кодирования.
Существует золотое правило: если класс не допускает, по крайней мере, двух существенно отличающихся реализаций, то что-то явно не в порядке с этим классом, это просто замаскированная реализация, а не представление абстрактного понятия. Во многих случаях для ответа на вопрос: "Достаточно ли интерфейс класса независим от реализации?" — надо указать, возможна ли для класса схема обычных вычислений.