Шаблон Visitor. Проблема

Опубликовал read-php в 11.02.2011 Категория: Выполнение задач и представление результатов в PHP

Вспомните о примере шаблона Composite. Для игры мы создали армию компонентов, так что с целым и его частями можно было обращаться попеременно. Мы видели, что операции можно встроить в компоненты. Обычно объекты-листья выполняют операцию, а объекты-композиты вызывают свои дочерние объекты, чтобы выполнить эту операцию.

class Army extends CompositeUnit {

function bombardStrength() {

$ret = 0;

foreach( $this->units() as $unit ) {

$ret += $unit->bombardStrength();

}

return $ret;

}

}

class LaserCannonUnit extends Unit { function bombardStrength() { return 44;

}

}

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

Ниже приведен пример функции, которая выдает текстовый информационный дамп об узлах-»листьях». Ее можно добавить к абстрактному классу unit.

// Unit

function textDump( $num=0 ) { $ret = «»; $pad = 4 * $num;

$ret .= sprintf ( «%{$pad}s», ,,n );

$ret .= get_class($this) . «: «;

$ret .= «Огневая мощь: » . $this-»bombardStrength() . «\n»;

return $ret;

}

i

Этот метод затем можно переопределить в классе CompositeUnit так.

// CompositeUnit

function textDump( $num=0 ) {

$ret = parent::textDump( $num ); foreach ( $this-»units as $unit ) {

$ret .= $unit-»textDump( $num .+ 1 ); }

return $ret;

}

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

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

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

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

Комментариев нет

Добавить комментарий