有一个类型码,会影响类的行为,但你无法通过继承手法消除它。
以状态对象取代类型码。
动机:
如果类型码的值在对象生命期中发生变化或其他原因使得宿主类不能被继承。
如果打算在本次重构后以replace conditional with polymorphism简化一个算法,那么选择strategy,如果打算搬移与状态相关的数据,而且把新建对象视为一种变迁状态,选择state。
做法:
使用self encapsulate field将类型码自我封装起来。
新建一个类,根据类型码的用途为它命名,这就是一个状态对象。
为这个新类添加子类,每个子类对应一种类型码。
=》比起逐一添加,一次性加入所有必要地子类可能更简单些。
在超类中建立一个抽象的查询函数,用以返回类型码。在每个子类中覆写该函数,返回确切的类型码。
在源类中建立一个字段,用于保存新建的状态对象。
调整源类中负责查询类型码的函数,将查询动作转发给状态对象。
调整源类中为类型码设值的函数,将一个恰当的状态对象子类赋值给“保存状态对象”的那个字段。
旧方法
class Employee{
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
Employee(int type){
_type = type;
}
int payAmount(){
switch(_type){
case ENGINEER:
return _monthlySalary;
case SALESMAN:
return _monthlySalary + _commission;
case MANAGER:
return _monthlySalary + _bonus;
default:
throw new RuntimeException();
}
}
}
新方法
class Engineer extends EmployeeType{
int getTypeCode(){
return Employee.ENGINEER;
}
}
class Manager extends EmployeeType{
int getTypeCode(){
return Employee.MANAGER;
}
}
class Salesman extends EmployeeType{
int getTypeCode(){
return Employee.SALEMAN;
}
}
class Employee...
private employeeType _type;
int payAmount(){
switch(getType()){
case EmployeeType.ENGINEER:
return _monthlySalary;
case EmployeeType.SALESMAN:
return _monthlySalary + _commission;
case EmployeeType.MANAGER:
return _monthlySalary + bonus;
default;
throw new RuntimeException();
}
}
int getType(){
return _type.getTypeCode();
}
void setType(int arg){
_type = EmployeeType.newType(arg);
}
class employeeType...
static EmployeeType newType(int code){
switch(code){
case ENGINEER:
return new Engineer();
case SALESMAN:
return new Salesman();
case MANAGER:
return new Manager();
default:
throw new IllegalArgumentException();
}
}
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;