replace type code with class(重构)用类替换类型码
2013-08-14 09:35
811 查看
在实际编程中,经常会遇到一些这样的问题:对于一类事物,经过会有一些不变的常量。例如:季节有春夏秋冬,方向有东西南北,状态有一二三四等等。通常的解决办法是使用类型码:也就是通常所说的类常量。
对于这种解决方法,存在者许多问题。例如:类型不安全、错误的赋值等。可以使用【用类代替类型码】重构来解决这类问题。
先简单介绍一下【用类代替类型码】重构:
使用场合:类中有数字或其他类型的类型码,这些类型码不影响类的行为。
解决方法:用类来替代这些类型码。
动机:数值码、枚举都是C语言的普通特性。通过有意义的命名使得它们变得可读,但是问题在于编译器关注的是它们底层的数值。编译器的类型检查也是根据数值而不是有意义的名称。任何以类型码作为参数的方法期望接收数字,但是它们不能强制使用有意义的类型码。从而降低了可读性,同时也将会是错误的源泉(a
source of bugs)。如果使用类来替代数值码,那么编译器就会进行类型检查。
接下来就具体介绍一下【提取方法】重构的实施过程。
为类型码创建一个新类,并且这个类中持有一个与类型码匹配的字段。并为这个字段提供getter方法。同时还需要一组静态变量,这些变量包括了所有可能的新类的实例。提供一个静态方法,接收一个类型码的参数并返回一个合适的类实例。
使用新类来改变原有类的实现。
编译并测试。
为原类中每个使用类型码的方法创建一个使用新类型的方法,并用新方法代替原方法。
修改客户程序,使用新接口。
每次修改客户程序后都进行编译和测试。
删除使用类型码的旧方法,并且删除类型码。
编译并测试。
现在给出一个简单的重构过程来加深理解。
[java] view
plaincopy
public class Person {
public static final int O = 0;
public static final int A = 1;
public static final int B = 2;
public static final int C = 3;
private int _bloodGroup;
public Person(int bloodGroup) {
_bloodGroup = bloodGroup;
}
public void setBloodGroup(int bloodGroup){
_bloodGroup = bloodGroup;
}
public int getBloodGroup(){
return _bloodGroup;
}
}
首先为类型码创建一个新类BloodGroup。
[java] view
plaincopy
public class BloodGroup {
public static final BloodGroup O = new BloodGroup(0);
public static final BloodGroup A = new BloodGroup(1);
public static final BloodGroup B = new BloodGroup(2);
public static final BloodGroup C = new BloodGroup(3);
private static final BloodGroup[] _values = {O,A,B,C};
private int _code;
public BloodGroup(int code) {
_code = code;
}
public int getCode(){
return _code;
}
public static BloodGroup code(int arg){
return _values[arg];
}
}
然后用新类中的类型码替换Person类中的类型码。
[java] view
plaincopy
public class Person {
public static final int O = BloodGroup.O.getCode();
public static final int A = BloodGroup.A.getCode();
public static final int B = BloodGroup.B.getCode();
public static final int C = BloodGroup.C.getCode();
private BloodGroup _bloodGroup;
public Person(int bloodGroup) {
_bloodGroup = BloodGroup.code(bloodGroup);
}
public void setBloodGroup(int bloodGroup){
_bloodGroup = BloodGroup.code(bloodGroup);
}
public int getBloodGroup(){
return _bloodGroup.getCode();
}
}
现在需要在运行时检查BloodGroup类型,为了能够从这个变化中真正的得到好处,需要让Person类的客户程序使用BloodGroup类型来代替原有的整数类型。为Person类添加使用BloodGroup类型的构造函数和getter/setter方法。
[java] view
plaincopy
public class Person {
private BloodGroup _bloodGroup;
public Person(BloodGroup bloodGroup) {
_bloodGroup = bloodGroup;
}
public void setBloodGroup(BloodGroup bloodGroup){
_bloodGroup = bloodGroup;
}
public BloodGroup getBloodGroup(){
return _bloodGroup;
}
}
如果没有客户程序使用BloodGroup中的getCode()和code()方法,可以将其设置为private。
[java] view
plaincopy
private int getCode(){
return _code;
}
private static BloodGroup code(int arg){
return _values[arg];
}
重构结束!
最后总结一下【用类替换类型码】的优缺点:
优点:更好的避免非法赋值和比较。
缺点:比使用不安全类型要求更多的代码。
对于这种解决方法,存在者许多问题。例如:类型不安全、错误的赋值等。可以使用【用类代替类型码】重构来解决这类问题。
先简单介绍一下【用类代替类型码】重构:
使用场合:类中有数字或其他类型的类型码,这些类型码不影响类的行为。
解决方法:用类来替代这些类型码。
动机:数值码、枚举都是C语言的普通特性。通过有意义的命名使得它们变得可读,但是问题在于编译器关注的是它们底层的数值。编译器的类型检查也是根据数值而不是有意义的名称。任何以类型码作为参数的方法期望接收数字,但是它们不能强制使用有意义的类型码。从而降低了可读性,同时也将会是错误的源泉(a
source of bugs)。如果使用类来替代数值码,那么编译器就会进行类型检查。
接下来就具体介绍一下【提取方法】重构的实施过程。
为类型码创建一个新类,并且这个类中持有一个与类型码匹配的字段。并为这个字段提供getter方法。同时还需要一组静态变量,这些变量包括了所有可能的新类的实例。提供一个静态方法,接收一个类型码的参数并返回一个合适的类实例。
使用新类来改变原有类的实现。
编译并测试。
为原类中每个使用类型码的方法创建一个使用新类型的方法,并用新方法代替原方法。
修改客户程序,使用新接口。
每次修改客户程序后都进行编译和测试。
删除使用类型码的旧方法,并且删除类型码。
编译并测试。
现在给出一个简单的重构过程来加深理解。
[java] view
plaincopy
public class Person {
public static final int O = 0;
public static final int A = 1;
public static final int B = 2;
public static final int C = 3;
private int _bloodGroup;
public Person(int bloodGroup) {
_bloodGroup = bloodGroup;
}
public void setBloodGroup(int bloodGroup){
_bloodGroup = bloodGroup;
}
public int getBloodGroup(){
return _bloodGroup;
}
}
首先为类型码创建一个新类BloodGroup。
[java] view
plaincopy
public class BloodGroup {
public static final BloodGroup O = new BloodGroup(0);
public static final BloodGroup A = new BloodGroup(1);
public static final BloodGroup B = new BloodGroup(2);
public static final BloodGroup C = new BloodGroup(3);
private static final BloodGroup[] _values = {O,A,B,C};
private int _code;
public BloodGroup(int code) {
_code = code;
}
public int getCode(){
return _code;
}
public static BloodGroup code(int arg){
return _values[arg];
}
}
然后用新类中的类型码替换Person类中的类型码。
[java] view
plaincopy
public class Person {
public static final int O = BloodGroup.O.getCode();
public static final int A = BloodGroup.A.getCode();
public static final int B = BloodGroup.B.getCode();
public static final int C = BloodGroup.C.getCode();
private BloodGroup _bloodGroup;
public Person(int bloodGroup) {
_bloodGroup = BloodGroup.code(bloodGroup);
}
public void setBloodGroup(int bloodGroup){
_bloodGroup = BloodGroup.code(bloodGroup);
}
public int getBloodGroup(){
return _bloodGroup.getCode();
}
}
现在需要在运行时检查BloodGroup类型,为了能够从这个变化中真正的得到好处,需要让Person类的客户程序使用BloodGroup类型来代替原有的整数类型。为Person类添加使用BloodGroup类型的构造函数和getter/setter方法。
[java] view
plaincopy
public class Person {
private BloodGroup _bloodGroup;
public Person(BloodGroup bloodGroup) {
_bloodGroup = bloodGroup;
}
public void setBloodGroup(BloodGroup bloodGroup){
_bloodGroup = bloodGroup;
}
public BloodGroup getBloodGroup(){
return _bloodGroup;
}
}
如果没有客户程序使用BloodGroup中的getCode()和code()方法,可以将其设置为private。
[java] view
plaincopy
private int getCode(){
return _code;
}
private static BloodGroup code(int arg){
return _values[arg];
}
重构结束!
最后总结一下【用类替换类型码】的优缺点:
优点:更好的避免非法赋值和比较。
缺点:比使用不安全类型要求更多的代码。
相关文章推荐
- 重构手法31:Replace Type Code with Subclass (以子类取代类型码)
- 重构手法30:Replace Type Code with Class (以类取代类型码)
- 重构之2.Replace Type Code with Class(以类取代类型码)
- 重构手法30:Replace Type Code with Class (以类取代类型码)
- 重构手法31:Replace Type Code with Subclass (以子类取代类型码)
- 重构手法32:Replace Type Code with State/Strategy (以状态/策略取代类型码)
- ReplaceTypeCodeWithClass(以类取代类型码)
- Eclipse重构——Replace TypeCode with Class
- Eclipse重构——Replace TypeCode with Class
- Replace Type Code with Class (以类取代类型码)
- 重构之3.Replace Type Code with Subclasses(以子类取代类型码)
- 重构-代替类型代码几中方式的比较(Replace type code with ...)
- 8.13 replace type code with class(以类取代类型码)
- 重构之4.Replace Type Code with State/Strategy(以State/Strategy取代类型码)
- 8.15 replace type code with state/strategy (以state/strategy取代类型码)
- Replace Type Code with Class(以类取代型别码)
- Refactor: replace type code with class (c++)
- Replace Type Code With Class和Replace Type Code With Subclass和Replace Type Code With State/Strategy
- Replace Type Code with Subclasses (以子类取代类型码)
- 重新组织数据之十三 :Replace Type Code with Class(以类取代型别码)