Книга: Экстремальное программирование. Разработка через тестирование
Накапливающий параметр (Collecting Parameter)
Накапливающий параметр (Collecting Parameter)
Как можно сформировать результат операции, если она распределена между несколькими объектами? Используйте параметр, в котором будут накапливаться результаты операции.
Простым примером является интерфейс java.io.Externalizable. Метод writeExternal этого интерфейса осуществляет запись объекта и всех объектов, на которые ссылается данный объект. Чтобы обеспечить общую запись, все записываемые объекты должны взаимодействовать друг с другом, поэтому методу передается параметр – объект класса ObjectOutput, – в котором осуществляется накопление:
java.io.Externalizable
public interface Externalizable extends java.io.Serializable {
void writeExternal(ObjectOutput out) throws IOException;
}
Добавление параметра-накопителя зачастую является последствием использования шаблона «Компоновщик» (Composite). В начале разработки JUnit не было необходимости накапливать результаты выполнения нескольких тестов в объекте TestResult до тех пор, пока в инфраструктуру не была добавлена возможность создания и запуска нескольких тестов.
Необходимость использования параметра-накопителя возникает в ситуации, когда возрастает сложность объекта, получаемого в результате комплексной операции. Например, представьте, что нам необходимо реализовать вывод объекта Expression на экран в виде строки символов. Если обычная, не структурированная строка – это все, что нам нужно, значит, конкатенации будет вполне достаточно:
testSumPrinting() {
Sum sum = new Sum(Money.dollar(5), Money.franc(7));
assertEquals("5 USD + 7 CHF", sum.toString());
}
String toString() {
return augend + " + " + addend;
}
Однако если мы хотим отобразить объект Expression в виде древовидной структуры, код может выглядеть следующим образом:
testSumPrinting() {
Sum sum = new Sum(Money.dollar(5), Money.franc(7));
assertEquals("+nt5 USDnt7 CHF", sum.toString());
}
В этом случае придется воспользоваться параметром-накопителем:
String toString() {
IndentingStream writer = new IndentingStream();
toString(writer);
return writer.contents();
}
void toString(IndentingWriter writer) {
writer.println("+");
writer.indent();
augend.toString(writer);
writer.println();
addend.toString(writer);
writer.exdent();
}
- Команда (Command)
- Объект-значение (Value Object)
- Нуль-объект (Null Object)
- Шаблонный метод (Template Method)
- Встраиваемый объект (Pluggable Object)
- Встраиваемый переключатель (Pluggable Selector)[26]
- Фабричный метод (Factory Method)
- Самозванец (Imposter)
- Компоновщик (Composite)
- Накапливающий параметр (Collecting Parameter)
- Одиночка (Singleton)