Экстремальное программирование. Разработка через тестирование - [9]

Шрифт
Интервал

Используя объекты-значения, не нужно беспокоиться о наложении имен. Если у меня есть пять долларов ($5), они всегда гарантированно будут оставаться именно пятью долларами ($5). Если вдруг кому-то понадобятся $7, придется создать новый объект.


$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

Сделать переменную amount закрытым членом класса

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()


Одно из следствий использования шаблона «Объект-значение» заключается в том, что все операции должны возвращать результаты в виде новых объектов, как было покзано в главе 2. Другое следствие заключается в том, что объекты-значения должны реализовывать метод equals(), операцию проверки равенства, потому что одни $5 ничем не отличаются от других.


$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

Сделать переменную «amount» закрытым членом

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()

hashCode()


Кроме того, если использовать Dollar в качестве ключа хеш-таблицы, вместе с equals() придется реализовать и hashCode(). Добавим этот пункт в список задач и вернемся к нему, когда это будет необходимо.

Вы ведь не собираетесь немедленно приступать к реализации метода equals()? Отлично, я тоже об этом не думаю. Ударив себя линейкой по руке, я стал размышлять над тем, как протестировать равенство. Для начала $5 должны быть равны $5:


public void testEquality() {

assertTrue(new Dollar(5). equals(new Dollar(5)));

}


Полоска окрасилась красным. Поддельная реализация могла бы просто вернуть значение true:


Dollar

public boolean equals(Object object) {

return true;

}


Конечно, мы с вами знаем, что на самом деле true – это «5 == 5», что, в свою очередь, означает «amount == 5», что соответствует «amount == dollar.amount». Но если бы я сразу проследил все эти шаги, я не смог бы продемонстрировать третью и наиболее консервативную методику реализации – триангуляцию.

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

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

Итак, для триангуляции нам понадобится второй пример. Как насчет того, чтобы проверить $5!= $6?


public void testEquality() {

assertTrue(new Dollar(5). equals(new Dollar(5)));

assertFalse(new Dollar(5). equals(new Dollar(6)));

}

Теперь необходимо обобщить равенство (equality):


Dollar

public boolean equals(Object object) {

Dollar dollar = (Dollar)object;

return amount == dollar.amount;

}


$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

Сделать переменную amount закрытым членом класса

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()

hashCode()


Мы могли бы использовать триангуляцию и для управления обобщением метода times(). Если бы у нас были примеры $5 * 2 = $10 и $5 * 3 = $15, нам не смогли бы просто возвращать константу.

Думаю, триангуляция – довольно интересная вещь. Я использую ее в случае, если не знаю, как выполнять рефакторинг. Если же я представляю, как устранить дублирование между кодом и тестами и создать более общее решение, я просто создаю его. С какой стати я должен создавать еще один тест, если сразу могу выполнить обобщение?

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


$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

Сделать переменную amount закрытым членом класса

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()

hashCode()

Равенство значению null

Равенство объектов


Итак, сейчас операция проверки равенства реализована полностью. Но как учесть сравнение со значением null и сравнение c другими объектами? Это часто используемые операции, пока они нам еще не нужны, поэтому мы просто добавим их в список задач.

Теперь, когда у нас есть операция проверки равенства, можно напрямую сравнивать объекты Dollar. Это позволит нам сделать переменную amount закрытой, какой и должна быть добропорядочная переменная экземпляра. Резюмируем все вышесказанное:

• поняли, что для использования шаблона проектирования «Объект-значение» необходимо реализовать операцию проверки равенства;

• создали тест для этой операции;

• реализовали ее простейшим способом;

• продолжили тестирование (вместо того, чтобы сразу приступить к рефакторингу);

• выполнили рефакторинг так, чтобы охватить оба теста сразу.

4. Данные должны быть закрытыми

$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10


Рекомендуем почитать
Язык PL/SQL

В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.


Введение в Direct3D8

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


Пишем драйвер Windows на ассемблере

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


Язык программирования С# 2005 и платформа .NET 2.0.

В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML.


Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса

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


Самоучитель UML

Самоучитель UMLПервое издание.В книге рассматриваются основы UML – унифицированного языка моделирования для описания, визуализации и документирования объектно-ориентированных систем и бизнес-процессов в ходе разработки программных приложений. Подробно описываются базовые понятия UML, необходимые для построения объектно-ориентированной модели системы с использованием графической нотации. Изложение сопровождается примерами разработки отдельных диаграмм, которые необходимы для представления информационной модели системы.