范例(Examples)
class IntRange {
private int _low, _high;
boolean includes(int arg) {
return arg >= _low && arg <= _high;
}
void grow(int factor) {
_high = _high * factor;
}
IntRange(int low, int high) {
_low = low;
_high = high;
}
為了封裝_low和_high這兩個值域,我先定義[取值/設值函數](如果此前沒有定義的話),并使用它們:
class IntRange {
private int _low, _high;
boolean includes(int arg) {
return arg >= _low && arg <= _high;
}
void grow(int factor) {
_high = _high * factor;
}
int getLow() {
return _low;
}
int getHigh() {
return _high;
}
void setLow(int arg) {
_low = arg;
}
void setHigh(int arg) {
_high = arg;
}
使用本項重構時,一般說來,設值函數被認為應該在[對象創建后]才使用,所以初始化過程中的行為有可能與設值函數的行為不同。這種情況下,我也許在構造函數中直接訪問值域,要不就是建立另一個獨立的初始化函數:
IntRange(int low, int high) {
initialize(low, high);
}
private void initialize(int low, int high) {
_low = low;
_high = high;
}
一旦你擁有一個subclass,上述所有動作的價值就體現出來了。如下所示:
class CappedRange extends IntRange {
CappedRange(int low, int high, int cap) {
super(low, high);
_cap = cap;
}
private int _cap;
int getCap() {
return _cap;
}
int getHigh() {
return Math.min(super.getHigh(), getCap());
}
}
現在,我可以CappedRange class中覆寫getHigh(),從而加入對cap的考慮,而不必修改IntRange class的任何行為。