`
IT-future
  • 浏览: 29724 次
  • 来自: ...
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

代码复用的规则(下)

阅读更多

  消除case / if语句

  要尽量避免在代码中出现判断语句,来测试一个对象是否某个特定类的实例。通常,如果你需要这么做,那么,重新设计可能会有所帮助。我在工作中遇到这样的一个问题:我们在使用JAVA做XML解析时,对每个标签映射了一个JAVA类,采用SAX(简单的XML接口API:Simple API for XML)模型。结果,代码中反复出现了大量的判断语句,来测试当前的标签类型。为此,我们重新设计了DTD(文档类型定义:Document Type Definition),为每个标签增加了一个固定的属性:classname,而且重新设计了每个标签映射的JAVA类的接口,统一了每个对象的操作:
  addElement(Element aElement); //增加子元素
  addAttribute(String attName, String attValue); //增加属性;

  则彻底消除了所有的测试当前的标签类型的判断语句。每个对象通过 Class.forName(aElement.attributes.getAttribute("classname")).newInstence(); 动态创建,

  减少参数个数

  有大量参数需要传递的方法,通常很难阅读。我们可以将所有参数封装到一个对象中来完成对象的传递,这也有利于错误跟踪。

  许多程序员因为,太多层的对象包装对系统效率有影响。是的,但是,和它带来的好处相比,我们宁愿做包装。毕竟,"封装"也是OO的基本特性之一,而且,"每个对象完成尽量少(而且简单)的功能",也是OO的一个基本原则。

  类层次的最高层应该是抽象类

  在许多情况下,提供一个抽象基类有利做特性化扩展。由于在抽象基类中,大部分的功能和行为已经定义好,使我们更容易理解接口设计者的意图是什么。

  由于JAVA不允许"多继承",从一个抽象基类继承,就无法再从其它基类继承了。所以,提供一个抽象接口(interface)是个好主意,一个类可以实现多个接口,从而模拟实现了"多继承",为类的设计提供了更大的灵活性。

  尽量减少对变量的直接访问

  对数据的封装原则应该规范化,不要把一个类的属性暴露给其它类,而是应该通过访问方法去保护他们,这有利于避免产生波纹效应。如果某个属性的名字改变,你只需要修改它的访问方法,而不是修改所有相关的代码。

  子类应该特性化,完成特殊功能

  如果一个子类只是使一个组件变成组件管理器,而不是实现接口功能,或者,重载某个功能,那么,就应该使用一个外部的容器类,而不是创建一个子类。

  建议:类层次结构图,不要太深;

  例如:下面的接口定义了组件的功能:发送消息;类Transceiver实现了该接口;而其子类Pool只是管理多个Transceiver对象,而没有提供自己的接口实现。建议使用组合方式,而不是继承!

public interface ITransceiver{
  public abstract send(String msg);
}

public class Transceiver implements ITransceiver {
  public send(String msg){
    System.out.println(msg);
  }
}

//使用继承方式的实现
public class Pool extends Transceiver{
  private List  pool = new Vector();
  public void add(Transceiver aTransceiver){
    pool.add(aTransceiver);
}
public Transceiver get(int index){
    pool.get(index);
}
}

//使用组合方式的实现
public class Pool {
  private List  pool = new Vector();
  public void add(Transceiver aTransceiver){
    pool.add(aTransceiver);
}
public Transceiver get(int index){
    pool.get(index);
}
}
  拆分过大的类

  如果一个类有太多的方法(超过50个),那么它可能要做的工作太多,我们应该试着将它的功能拆分到不同的类中,类似于规则四。

  作用截然不同的对象应该拆分

  在构建的过程中,你有时会遇到这样的问题:对同样的数据,有不同的视图。某些属性描述的是数据结构怎样生成,而某些属性描述的是数据结构本身。最好将这两个视图拆分到不同的类中,从类名上就可以区分出不同视图的作用。

  类的域、方法也应该有同样的考虑!

  尽量减少对参数的隐含传递

  两个方法处理类内部同一个数据(域),并不意味着它们就是对该数据(域)做处理。许多时候,该数据(域)应该作为方法的参输入数,而不是直接存取,在工具类的设计中尤其应该注意。例如:

public class Test{
  private List  pool = new Vector();
  public void testAdd(String str){
    pool.add(str);
}
public Object testGet(int index){
    pool.get(index);
}
}
  两个方法都对List对象pool做了操作,但是,实际上,我们可能只是想对List接口的不同实现Vector、ArrayList等做存取测试。所以,代码应该这样写:
public class Test{
  private List  pool = new Vector();
  public void testAdd(List  pool, String str){
    pool.add(str);
}
public Object testGet(List  pool, int index){
    pool.get(index);
 



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics