43
eXtreme Programming XP Тема 3 Тема 3

EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Embed Size (px)

Citation preview

Page 1: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

eXtreme ProgrammingXPXP

Тема 3Тема 3Тема 3Тема 3

Page 2: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Пусть есть некоторая информационная система для банков.

В качестве основной валюты для расчетов используется доллар, для работы с которым был реализован класс Dollar.

В условиях кризиса требовалось перевести систему на мультивалютные расчеты.

Page 3: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

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

public void testMultiplication(){

Dollar five=new Dollar(5);five.times(2);assertEquals(10.,five.amount);

}

public class Dollar {

double amount;Dollar (double amount){}

void times(int mult){}

}

Page 4: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

При объявлении переменной amount:double amount=5*2;

В методе times:void times(int mult){ amount=5*2;}

Изменения должны быть и в конструкторе, и в методе times:

Dollar (double amount){this.amount=amount;}

void times(int mult) {amount*=mult;}

Page 5: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 6: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Изменение метода times:Dollar times(int mult){

return new Dollar(amount*mult);}

Изменение теста:public void testMultiplication(){

Dollar five=new Dollar(5);Dollar product=five.times(2);

assertEquals(10.,product.amount);product=five.times(3);assertEquals(15.,product.amount);

}

XPXP

Page 7: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 8: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Не работает другой тест:public void testEquality()

{

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

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

}

Требуется изменить метод equals:public boolean equals(Object obj)

{

Dollar dollar=(Dollar)obj;

return amount==dollar.amount;

}

XPXP

Page 9: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 10: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Меняем тест – сравниваем на равенство объекты:

public void testMultiplication()

{

Dollar five=new Dollar(5);

assertEquals(new Dollar(10),five.times(2));

assertEquals(new Dollar(15),five.times(3));

}

XPXP

Page 11: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 12: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Добавляем новый класс Franc (код из класса Dollar);

Пишем тест:

public void testFrancMultiplication()

{

Franc five=new Franc(5);

assertEquals(new Franc(10),five.times(2));

assertEquals(new Franc(15),five.times(3));

}

XPXP

Page 13: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 14: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Создадим класс Money, от которого наследуют Dollar и Franc

Перенесем в него переменную amount.

Для выполнения всех тестов требуется сделать ее protected.

XPXP

Page 15: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Меняем в классе Dollar метод equals – перенос на тип данных Money

public boolean equals(Object obj){

Money money=(Money)obj;return amount==money.amount;

}

Переносим метод в класс Money и удаляем из классов Dollar и Franc.

Тест:public void testEquality(){

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

assertTrue(new Franc(5).equals(new Franc(5))); assertFalse(new Franc(5).equals(new Franc(6)));}

XPXP

Page 16: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 17: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Тест:public void testEquality(){

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

}

Изменение метода:public boolean equals(Object obj){

Money money=(Money)obj;return amount==money.amount && getClass().equals(money.getClass());

}

XPXP

Page 18: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 19: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Методы times могут возвращать Money

Money times(int mult)

{

return new Dollar(amount*mult);

}

В результате классы почти одинаковые -> хочется сделать только один класс

XPXP

Page 20: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

В класс Money добавим фабричный метод создания объекта Dollar:static Dollar dollar(double amount){ return new Dollar(amount);}

Меняем принцип создания объекта в тесте:public void testMultiplication(){

Money five=Money.dollar(5);assertEquals(Money.dollar(10),five.times(2));assertEquals(Money.dollar(15),five.times(3));

}

Осталась ошибка – метод times не определен в классе Money

XPXP

Page 21: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Делаем класс Money абстрактным, добавляя в него абстрактный метод times.

abstract class Money

{

protected double amount;

abstract Money times(int mult);

}

Меняем фабричный метод с точки зрения возвращаемого значенияstatic Money dollar(double amount)

{ return new Dollar(amount); }

XPXP

Page 22: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Делаем те же действия с классом Franc

Меняем тестыpublic void testEquality()

{

assertTrue(Money.dollar(5).equals(Money.dollar(5)));

assertFalse(Money.dollar(5).equals(Money.dollar(6)));

assertTrue(Money.franc(5).equals(Money.franc(5)));

assertFalse(Money.franc(5).equals(Money.franc(6)));

assertFalse(Money.franc(5).equals(Money.dollar(5)));

}

XPXP

Page 23: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 24: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Добавляем метод для получения названия валюты в классы Dollar и Franc и абстрактный метод в класс Money:abstract String currency();

String currency(){ return "USD";}

String currency(){ return "CHF";}

Тестpublic void testCurrency()

{

assertEquals("USD",Money.dollar(1).currency());

assertEquals("CHF",Money.franc(1).currency());

}

XPXP

Page 25: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Вводим символьную переменную для обозначения валюты в класс Money и переносим функцию currency полностью в класс Moneyabstract class Money {

protected double amount; protected String currency;…String currency(){ return currency; }

}

Конструкторы должны инициализировать эту строку, например, Franc (double amount){

this.amount=amount;this.currency="CHF";

}

XPXP

Page 26: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Конструкторы производных классов похожи -> можно инициализировать переменную currency внутри конструктора базового класса:public Money(double amount, String currency)

{

this.amount=amount;

this.currency=currency;

}

Конструкторы производных классов выглядят, например, так:Franc (double amount)

{

super(amount,"CHF");

}

Можно добавить второй параметр с обозначением валюты и передавать его конструктору базового класса

XPXP

Page 27: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 28: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Функция times класса Dollar выглядит так:Money times(int mult){ return Money.dollar(amount*mult);}

Вернемся к вызову конструктора:Money times(int mult){ return new Dollar(amount*mult,“USD");}

Строку с названием валюты можно получить из поля currency-> переносим в класс Money (класс перестает быть абстрактным)Money times(int mult){ return new Money(amount*mult,currency);}

Тест не срабатывает – сравнение имен классов (один объект класса Dollar, другой – класса Money).

XPXP

Page 29: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Вернемся к методам times внутри производных классов, например, в DollarMoney times(int mult)

{ return new Dollar(amount*mult,currency);}

Тесты сработали. Добавляем тест для сравнения объектов, созданных с помощью Money и Dollarpublic void testDifferentClasses()

{

assertTrue(new Money(10,"CHF").equals(new Franc(10,"CHF")));

}

Тест не сработал.

XPXP

Page 30: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Меняем equals – сравнение названий валют, а не имен классов.public boolean equals(Object obj)

{

Money money=(Money)obj;

return amount==money.amount && currency.equals(money.currency);

}

Тесты сработали.Снова отказываемся от методов times

производных классов. Тесты сработали.

XPXP

Page 31: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 32: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Производные классы имеют только конструкторы. Отказываемся от них. Методы-фабрики должны вызывать конструктор класса Money.static Money franc(double amount)

{

return new Money(amount,"CHF");

}

Тест на равенство объектов разных классов и умножение франков можно удалить.

XPXP

Page 33: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

XPXP

Page 34: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Реализуем тест:public void testSimpleAddition()

{

Money sum=Money.dollar(5).plus(Money.dollar(5));

assertEquals(sum,Money.dollar(10));

}

В класс Money добавляем функцию plus:

Money plus(Money added)

{

return new Money(amount+added.amount,currency);

}

XPXP

Page 35: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Обменный курсы должен знать банк -> создаем класс Bank (в нем метод reduce для перевода денег в конкретную валюту).

XPXP

Page 36: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Тест:public void testSimpleAddition(){

Money five=Money.dollar(5);Money sum=five.plus(five);Bank bank=new Bank();Money reduced=bank.reduce(sum, "USD");assertEquals(sum,Money.dollar(10));

}

В классе Bank должна быть заглушка:public class Bank {

Money reduce(Money source, String to){ return Money.dollar(10); }}

Метод plus возвращает Money.

XPXP

Page 37: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Тесты:public void testReduceMoney()

{

Bank bank=new Bank();

bank.addRate("CHF","USD",2);

Money result=bank.reduce(Money.franc(2), "USD");

assertEquals(Money.dollar(1),result);

}

public void testHashRates()

{

Bank bank=new Bank();

bank.addRate("CHF", "USD", 2);

assertTrue(bank.rate("CHF", "USD")==2.);

}

XPXP

Page 38: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

В классе Bank создаем хэш-таблицу:

private class Pair{

private String from;private String to;public Pair(String from, String to){

this.from=from;this.to=to;

}public boolean equals(Object obj){

Pair p=(Pair)obj;return from.equals(p.from) && to.equals(p.to);

}public int hashCode(){ return 0; }

}private Hashtable rates=new Hashtable();

XPXP

Page 39: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

void addRate(String from, String to, double rate)

{

rates.put(new Pair(from,to), new Double(rate));

}

double rate(String from, String to)

{

Double rate=(Double)rates.get(new Pair(from,to));

return rate.doubleValue();

}

XPXP

Page 40: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Делаем метод-заглушку класса Bank:

Money reduce(Money source,String to)

{

double rate=1;

if (source.currency.equals("CHF") && to.equals("USD"))

rate=2.;

if (source.currency.equals("USD") && to.equals("CHF"))

rate=1./2;

return new Money(source.amount/rate,to);

}

XPXP

Page 41: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Изменяем заглушку:

Money reduce(Money source,String to)

{

double rate=1;

Pair p=new Pair(source.currency,to);

if (rates.containsKey(p))

rate=rate(source.currency,to);

return new Money(source.amount/rate,to);

}

XPXP

Page 42: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Изменяем тест

public void testReduceMoney()

{

Bank bank=new Bank();

bank.addRate("CHF","USD",2);

Money result=bank.reduce(Money.franc(2), "USD");

assertEquals(Money.dollar(1),result);

result=bank.reduce(Money.dollar(2), "USD");

assertEquals(result,Money.dollar(2));

result=bank.reduce(Money.dollar(2), "CHF");

assertEquals(result,Money.franc(4));

}

Тест не работает, так как если курса нет, то в хэш-таблице ничего не будет найдено.

XPXP

Page 43: EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты

Добавлять надо два курса

void addRate(String from, String to, double rate)

{

rates.put(new Pair(from,to), new Double(rate));

rates.put(new Pair(to,from), new Double(1/rate));

}

XPXP