Книга: Экстремальное программирование. Разработка через тестирование

Накапливающий параметр (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();

}

Оглавление книги


Генерация: 1.315. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз