< 현재 구현해야할 목록 >
불필요한 하위 클래스를 제거하기 위해서 통화 개념을 도입해보자.
abstract class Money {
protected int amount;
abstract Money times(int multiplier);
abstract String currency();
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && getClass().equals(money.getClass());
}
static Money dollar(int amount) {
return new Dollar(amount);
}
static Money franc(int amount) {
return new Franc(amount);
}
}
// Franc
public class Franc extends Money{
public Franc(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return new Franc( amount * multiplier);
}
@Override
String currency() {
return "CHF";
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
public Dollar(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return new Dollar( amount * multiplier);
}
@Override
String currency() {
return "USD";
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
우리는 두 클래스를 모두 포함할 수 있는 동일한 구현을 원한다.
-> 통화를 인스턴스 변수에 저장하고, 메서더는 그것을 반환만하게 만들어 보자.
// Money
abstract class Money {
protected int amount;
abstract Money times(int multiplier);
protected String currency;
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && getClass().equals(money.getClass());
}
static Money dollar(int amount) {
return new Dollar(amount);
}
static Money franc(int amount) {
return new Franc(amount);
}
}
// Franc
public class Franc extends Money{
private String currency;
public Franc(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return new Franc( amount * multiplier);
}
Franc(int amount) {
this.amount = amount;
currency = "CHF";
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
private String currency;
public Dollar(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return new Dollar( amount * multiplier);
}
Dollar(int amount) {
this.amount = amount;
currency = "USD";
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
이렇게 바꾸면 에러가 발생한다. 우선은 놔두고 times()를 먼저 정리하자.
// Money
abstract class Money {
protected int amount;
abstract Money times(int multiplier);
protected String currency;
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && getClass().equals(money.getClass());
}
static Money dollar(int amount) {
return new Dollar(amount, "USD");
}
static Money franc(int amount) {
return new Franc(amount, "CHF");
}
}
// Franc
public class Franc extends Money{
private String currency;
public Franc(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return Money.franc(amount * multiplier);
}
Franc(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
private String currency;
public Dollar(int amount) {
this.amount = amount;
}
Money times(int multiplier) {
return Money.dollar( amount * multiplier);
}
Dollar(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
이제 두 생성장가 동일해졌기 때문에 구현을 상위 클래스에 올릴 수 있다.
// Money
abstract class Money {
protected int amount;
abstract Money times(int multiplier);
protected String currency;
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && getClass().equals(money.getClass());
}
Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
static Money dollar(int amount) {
return new Dollar(amount, "USD");
}
static Money franc(int amount) {
return new Franc(amount, "CHF");
}
}
// Franc
public class Franc extends Money{
private String currency;
Money times(int multiplier) {
return Money.franc(amount * multiplier);
}
Franc(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
private String currency;
Money times(int multiplier) {
return Money.dollar( amount * multiplier);
}
Dollar(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
< 현재 구현해야할 목록 >
우리는 지금까지