вопросы по дизайну составного шаблона

У меня есть вопрос о двух операциях, которые вы часто видите в примере схемы составного класса.
* GetDescidents
* GetChild(int)

Распространенным примером являются файлы и каталоги, я буду придерживаться этого. Допустим, интересующей нас операцией является Size, поэтому File имеет реальный размер, а Directory имеет Size, полученный в результате рекурсивной итерации GetDescidents. Все идет нормально. Мой вопрос связан с использованием клиентом GetDescidents. Скажем, вам нужны файлы в каталоге, которые являются изображениями для некоторой данной операции. Таким образом, на практике вы используете некоторую комбинацию GetDescidents и Children для возврата файлов изображений (в зависимости от того, нужны ли клиенту все вложенные файлы изображений или только на корневом уровне).

Итак, вопрос номер один: не лучше ли использовать метод GetImageFiles для композита, а не заставлять клиента разбираться в этом? И если это так, будет ли GetDescidents когда-либо практичным для предоставления клиентским вызывающим объектам (например, ImageViewer) вне композиции?

Второй вопрос о GetChild(int); является ли int индексом порядкового номера для возврата одного дочернего элемента? Уровень глубины в GetDescidents? Что может быть примером того, как клиент будет использовать этот метод?

С уважением,
Беррил


person Berryl    schedule 24.03.2011    source источник


Ответы (1)


Эти вопросы относятся не к составному шаблону как таковому, а к более серьезному вопросу о том, как вы разрабатываете API и недвусмысленно сообщаете о своих намерениях как разработчика класса.

Например, если вы хотите, чтобы ваш GetChild(int) давал индексированный непосредственный дочерний элемент, вы можете назвать его GetChildAtIndex(int index); если вы хотите, чтобы он давал дочерние элементы на определенном уровне в иерархии, вы можете назвать его GetChildrenAtLevel(int level) (обратите внимание, что это множественное число и возвращает коллекцию).

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

person Jordão    schedule 24.03.2011
comment
Точно. Мой вопрос заключается в том, имеет ли смысл когда-либо предоставлять дочерние операции клиентам, которые не являются частью композиции или, по крайней мере, имеют с ней очень близкие отношения, т. е. это внутренние операции для создания клиентская потребляемая операция, такая как GetFilesOfType(). - person Berryl; 24.03.2011
comment
@Berryl: это зависит от того, что представляет ваш класс. Паттерн — это всего лишь деталь реализации, главное — это концепция. - person Jordão; 24.03.2011