Как называется этот шаблон? - PullRequest
0 голосов
/ 26 января 2012

Я пишу спецификацию, в которой я хочу заявить (однозначно), что программист использует этот шаблон:

Мы должны применить несколько фильтров к данным, которые мы обрабатываем.Конфигурация позволяет создавать эти фильтры.Их может быть несколько или их нет.Мне не нужна эта логика в классе экспорта (потому что в будущем он может вырасти большим, с другими типами фильтров, которые мы не можем предвидеть сейчас).Я хочу, чтобы они запускались один за другим, поэтому я собираюсь попросить метод в классе экспорта: «addFilter», который должен хранить объекты во внутреннем массиве, а затем выполнять их при запуске самого процесса экспорта..

Я не знаю, достаточно ли ясен вопрос.Это похоже на цепочечную стратегию, но не совсем на стратегию, потому что вообще не обязательно иметь фильтр.

Опять вопрос: как мне назвать этот шаблон в спецификациях?


Редактировать: пример того, что я пытаюсь сделать:

$report = new Report();
$report->addFilter(new RemoveSpaces())
       ->addFilter(new SubstituteText($predefined_substitutions_array)
       ->addFilter(new FixCapitals())
       ->addFilter(new Encode("utf8"));
echo($report->generate());   // filters are actually used during generation.

Предположительно, пользователь должен иметь возможность решить, следует ли удалять RemoveSpaces или нет, какой текст заменить, использовать ли слова с большой буквы илинет, какую кодировку использовать и т. д. Некоторые фильтры, несомненно, будут добавлены в будущем по запросу пользователя (клиента, на самом деле).

После того, как эти факторы будут учтены, фильтры должны иметь простой интерфейс, который будет вызывать отчет:

foreach($this->filters as $current_filter) {
  $data = $this->filters[$current_filter]->applyTo($data);
}

Ответы [ 4 ]

2 голосов
/ 26 января 2012

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

В вашем конкретном случае это выглядит как Цепочка ответственности

Вы также можете искать *Шаблон 1007 * Декоратор также предназначен для реализации функций, подобных фильтру.

Кстати, другой шаблон, аналогичный вашему, это Шаблон команды .Так что в вашем случае generate из Report похоже на execute из Command, а фильтры - это команды в списке.

2 голосов
/ 26 января 2012

На ум пришла модель GoF «Цепочка ответственности». Вот описание из Википедии: http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

1 голос
/ 27 января 2012

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

Как ваш класс Report взаимодействует с классом Filter (или наоборот)?

Я не думаю, что это классическая цепь ответственности, потому что в этом случае каждый участник отвечает за вызов следующего участника, обычно с собственным кодом, выполняемым до или после.Подумайте о том, как Windows связывает WindProc с тем, где вы можете выполнять код до или после prio WindProc, и даже можете не вызывать его.

Эти объекты фильтра могут быть декораторами, если реализовать тот же интерфейс, что и основной объект, а затемони обертывают друг друга.Но ваш пример кода содержал объекты в простом списке.В декораторе вы часто видите это:

FilterA fA = new FilterA(coreObject);
FilterB fB = new FilterB(fA);
FilterC fC = new FilterC(fB);

Конечно, это не обязательно делать через конструктор, поэтому, как я уже сказал, нам нужно увидеть больше кода, чтобы узнать, если этобыл декоратором.

Я склонен думать, что вы шли за шаблоном «Трубы и фильтры», где выходные данные каждой операции являются входными данными следующей, но даже это неясно, не зная больше.Я не могу сказать, действует ли каждый фильтр на одну и ту же вещь (например, гигантскую строку), или предполагается, что каждый фильтр взаимодействует с каким-либо аспектом объектной модели отчета.

Например, если у отчета есть свойство объекта, которое является текущим Encoder, то, возможно, ваш Encode("utf8") фильтр просто действует как fcatory, который настраивает / устанавливает подкласс Encoder для работы со стратегией персистентности диска,Между тем ваш SubstituteText($predefined_substitutions_array) действует на коллекцию параметров, принадлежащую отчету, для замены значений времени выполнения.

Я бы предложил описать то, чего вы хотите достичь, а не столько, сколько достичь этого.

1 голос
/ 26 января 2012

Очень похоже на Цепочка ответственности . Обратите внимание, что каждый фильтр может решить не продолжать цепочку. И обычно есть «цепной» объект, который передается каждому последующему фильтру.

Если вам не нужна эта семантика цепочки, ее можно просмотреть просто как прокси вокруг целевого объекта.

...