首先我要使用Replace Type Code with State/Strategy(227).第一步骤是针对[与型别相依的行为]使用Self Encapsulate Field(171),确保任何时候都通过getting和setting两个函数来运用这些行为。由于多数代码来自其他classes,所以多数函数都已经使用getting函数。但构造函数(constructor)仍然直接访问价格代码:
class Movie...
public Movie(String name, int priceCode) {
_title = name;
_priceCode = priceCode;
}
我可以用一个setting函数来代替:
class Movie...
public Movie(String name, int priceCode) {
_title = name;
setPriceCode(priceCode);
}
现在我加入新class,并在price对象中提供[与型别相依的行为]。为了实现这一点,我在Price内加入一个抽象函数(abstract method),并在其所有subclasses中加上对应的具体函数(concrete method):
abstract class Price {
abstract int getPriceCode(); //取得价格代号
}
class ChildernsPrice extends Price {
int getPriceCode() {
return Movie.CHILDERNS;
}
}
class NewReleasePrice extends Price {
int getPriceCode() {
return Movie.NEW_RELEASE;
}
}
class RegularPrice extends Price {
int getPriceCode() {
return Movie.REGULAR;
}
}
现在,我需要修改Movie class内的[价格代号]访问函数(get/set函数,如下),让它们使用新class。下面是重构前的样子:
public int getPriceCode() {
return _priceCode;
}
public void setPriceCode(int arg) {
_priceCode;
}
private int _priceCode;
这个意味我必须在Movie class内保存一个price对象,而不再是保存一个_priceCode变量。此外我还需要修改访问函数:
class Movie...
public int getPriceCode() { //取得价格代号
return _price.getPriceCode();
}
public void setPriceCode(int arg) { //设定价格代码
switch(arg) {
case REGULAR: //普通片
_price = new RegularPrice();
break;
case CHILDERNS: //儿童片
_price = new ChildernsPrice();
break;
case NEW_RELEASE: //新片
_price = new NewReleasePrice();
break;
default:
throw new IllegalArument Exception("Incorrect Price Code");
}
}
private Price _price;