Posted on 2008-10-25 13:55
非鱼 阅读(2360)
评论(6) 编辑 收藏 所属分类:
面向对象设计 、
Java技术
2. instanceof检查链
这个问题是连续使用if ... else + instanceof检查来判断一个对象的类型,并采取不同的处理逻辑。示例代码如下:
public void method(Fruit fruit) {
if (fruit instanceof Apple) {
...
}
else if (fruit instanceof Orange) {
...
}
else if .....
}
这不是面向对象的方法,完全没有利用到多态的面向对象特性。我相信一个合格的程序员是不会写出这样的编码的,这一般是新手程序员,特别是对面向对象理解不深刻的程序员会犯的毛病。改正的方法就是在Fruit类中增加一个方法,并在Apple、Orange等子类中实现此方法:
public abstract class Fruit {
public int m();
}
当然,在环境允许的情况下,尽可能使用protected而不是public来定义这个方法。
现在我们来看一个复杂一点的,同样还是instanceof检查的问题,但这个检查只涉及了Fruit诸多子类中的一部分,而其他的子类,行为是一致的。这时候我们需要在Fruit中引入一致行为的实现:
public abstract class Fruit {
public int m() {
//一般的实现。
...
}
}
而更加复杂的行为需要对应复杂的设计,通过对具体水果的抽象,可以发现这些水果可以抽象为几个较为一般的类:
public abstract class Fruit {
public int m(){
...
}
}
public class TypeAFruit extends Fruit {
public int m(){
//特定类型的实现。
}
}
public class TypeBFruit extends Fruit {
public int m(){
// 特定类型的实现。
}
}
...
关于类的继承层次的问题,有一种说法是“原则上”控制在一定的数量之内。一般来说 这个说法是有道理的(特别是对初学者,它可以有效的避免“滥继承”),但不是放之四海皆准的道理,不要把它教条化。
说到继承层次,不得不提到抽象层次。我们总是在一定的抽象层次上解决问题,抽象层次决定了你解决问题的实现的复杂程度。设计以简洁为美,不要把设计复杂化。但简洁并不意味着“少”,简洁的真正涵义是:模型不比模型所表达的事物更加复杂,不要把“本来简单”的东西复杂化,也不要把本来复杂的东西简单化。
我所要表达的是,设计应该是简洁的,但不是“简单”的。“设计应该简单”的说法,是来自翻译的问题,还是来自理解的问题?简单会导向“偷工减料”,而简洁则要求不要在设计中加料(特别是废料)。
一个继承结构有多少层才是合适的?最上层的类或接口对应着“一般概念”,最下层的类一定可以实例化为具体的对象,这中间有多少“层”,就有多少抽象层次。决定抽象层次,也就是决定你的继承层次的原则有二:
- 客户代码的需要:客户代码是指调用你的类继承层次中的某些类的代码,客户代码需要知道某个层次的细节。此外需要注意的是,客户代码应该尽量使用最上层的“一般概念”。
- 重用的需要:在具体的不同类中存在相同代码的时候,就要考虑有没有可能进行抽象,形成一个用于重用目的的父类。
类继承层次的设计也不是一成不变的,按照上面这两个原则,当客户代码不再需要某个层次时,或者当重用代码不可能(一般标志就是大量的override)时,就要考虑改变继承体系的设计。
汗,感觉后面有点越扯越远了。。。
instanceof, inheritance, abstraction