Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет211/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   207   208   209   210   211   212   213   214   ...   256
11.3.3.3 Шаг 3: указание зависимостей 
Уточните определение классов, указав их зависимости от других классов. Различные виды 
зависимостей обсуждаются в $$12.2. Основными по отношению к проектированию следует считать 
отношения наследования и использования. Оба предполагают понимание того, что значит для класса 
отвечать за определенное свойство системы. Отвечать за что-либо не означает, что класс должен 
содержать в себе всю информацию, или, что его функции-члены должны сами проводить все 
необходимые операции. Как раз наоборот, каждый класс, имеющий определенный уровень 
ответственности, организует работу, перепоручая ее в виде подзадач другим классам, которые имеют 
меньший уровень ответственности. Но надо предостеречь, что злоупотребление этим приемом 
приводит к неэффективным и плохо понимаемым проектам, поскольку происходит размножение 
классов и объектов до такой степени, что вместо реальной работы производится только серия запросов 
на ее выполнение. То, что можно сделать в данном месте, следует сделать. 
Необходимость учесть отношения наследования и использования на этапе проектирования (а не только 
в процессе реализации) прямо вытекает из того, что классы представляют определенные понятия. 
Отсюда также следует, что именно компонент (т.е. множество связанных классов), а не отдельный 
класс, являются единицей проектирования. 
11.3.3.4 Шаг 4: определение интерфейсов 
Определите интерфейсы классов. На этой стадии проектирования не нужно рассматривать приватные 
функции. Вопросы реализации, возникающие на стадии проектирования, лучше всего обсуждать на 
шаге 3 при рассмотрении различных зависимостей. Более того, существует золотое правило: если 
класс не допускает по крайней мере двух существенно отличающихся реализаций, то что-то явно не в 


Бьерн Страуструп.
Язык программирования С++ 
 
295 
порядке с этим классом, это просто замаскированная реализация, а не представление абстрактного 
понятия. Во многих случаях для ответа на вопрос: "Достаточно ли интерфейс класса независим от 
реализации?"- надо указать, возможна ли для класса схема ленивых вычислений. 
Отметим, что общие базовые классы и друзья (friend) являются частью общего интерфейса класса (см. 
$$5.4.1 и $$12.4). Полезным упражнением может быть определение раздельного интерфейса для 
классов-наследников и всех остальных классов с помощью разбиения интерфейса на общую и 
закрытые части.
Именно на этом шаге следует продумать и описать точные определения типов аргументов. В идеале 
желательно иметь максимальное число интерфейсов со статическими типами, относящимися к области 
приложения (см. $$12.1.3 и $$12.4). 
При определении интерфейсов следует обратить внимание на те классы, где набор операций 
представлен более, чем на одном уровне абстракции. Например, в классе file у некоторых функций-
членов аргументы имеют тип file_descriptor (дескриптор_файла), а у других аргументы - строка 
символов, которая обозначает имя файла. Операции с file_descriptor работают на другом уровне 
(меньшем) абстракции, чем операции с именем файла, так что даже странно, что они относятся к 
одному классу. Возможно, было бы лучше иметь два класса: один представляет понятие дескриптора 
файла, а другой - понятие имени файла. Обычно все операции класса должны представлять понятия 
одного уровня абстракции. Если это не так, то стоит подумать о реорганизации и его, и связанных с ним 
классов. 


Достарыңызбен бөлісу:
1   ...   207   208   209   210   211   212   213   214   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет