潜鱼在渊

Concentrating on Architectures.

posts - 77, comments - 309, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

代码检查(2)

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)时,就要考虑改变继承体系的设计。


汗,感觉后面有点越扯越远了。。。


, ,


评论

# re: 编码问题(2)  回复  更多评论   

2008-10-25 18:07 by eng?
为什么java程序难以维护,就是你们这些所谓的“合格程序员”写的程序

# re: 编码问题(2)[未登录]  回复  更多评论   

2008-10-25 22:54 by Matthew
楼上写的不知啥意思,楼主讲得很好啊,要可扩展又能应对实际项目的需要。

# re: 编码问题(2)  回复  更多评论   

2008-10-26 00:39 by 非鱼
@Matthew
兄弟没有看懂楼上的话?我非常同意他的结论,我和比我在先的大量程序员们,不知道以前写出了多少烂程序,一路踩着大量的项目的尸体,才能变得聪明一点。但合格的程序员有不少,其中又有多少人是合格的老师或者说引导者呢?于是虽然从事这个职业的人越来越多,写出来的代码质量却未见提高。能够给你带来益处我当然高兴;我却仍然为自己知道的迟而感到遗憾。使后来者感到无助是我们这些先行者的错,他们可能会因此而走向极端,而我们要做的,不是把他们划到圈子之外。

# re: 编码问题(2)  回复  更多评论   

2008-10-26 12:49 by 隔叶黄莺
能把本来复杂的东西简单化

若不失完整的表达了需求何乐而不为

# re: 编码问题(2)  回复  更多评论   

2008-10-27 23:28 by 非鱼
@隔叶黄莺
能把本来复杂的东西简单化,就是舍弃一些不重要的细节,实际就是“抽象”了。如果抽象可以满足需求自然可以;否则必然要求在较低的抽象层次上建模。

# re: 编码问题(2)  回复  更多评论   

2008-10-28 17:15 by flybean
顶楼的说法有些欠妥。不仅仅是JAVA代码难维护的问题。

非鱼所举的例子,如果能来源于实际项目,效果会好一些。毕竟水果的这个例子不痛不痒。

只有注册用户登录后才能发表评论。


网站导航: