首先我要使用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;