代码整洁之道

  • 命名,多花些时间推敲命名, 有意义的命名非常重要。
    • 接口的命名,不使用“I”开头比较简洁,加上I以后是比较规范,但是比较繁琐以及废话。如果想区别接口和实现,不如在实现类中进行编码,比如添加后缀“Imp”,android以及jdk中的大多数接口都没有使用I。
    • 取名字带有简写要慎重, 比如“人事系统”的类, 前面都是“RSXT。。”,除了让快捷按钮找不到类以外,没有啥意义了,用包吧。
  • 函数,函数要短小,要职责明确,最好功能单一,参数最好不要超过两个,否则有顺序问题。
    • 合理的返回值可以使函数更加明了。
    • 封装Switch语句。
  • 注释,注释里面就有一堆问题要说了
    • 删除不必要的作者修改痕迹,这种东西应该留给源代码管理软件。
    • 删除你要准备注释掉,但是不想删的东西,他们丢不了,我担保。
    • 不要为了写注释而写注释。
    • 代码中令人费解和取巧的地方,甚至可以单独留作一个方法,强调注释,比如“开发取迭代次数”的例子
  • 格式,代码都是从左往右,从上往下读的
    • 空行代表全新的概念
    • 成员变量注释要慎重,影响可读性
  • 对象和数据结构
    • 过程式代码(使用数据结构)便于在不改动既有数据结构的前提下添加新函数,面向对象代码便于在不改动既有函数的前提下添加新类,反过来讲,过程式代码难以添加新数据结构,因为必须修改所有函数。面向对象代码难以添加新函数,因为必须修改所有类
    • 火车失事类型代码 a.getb().getc().getd()……这种代码是否违反德墨忒尔律,取决于b,c,d是数据结构还是对象,如果是对象,那么内部结构应该保持隐藏,这样做自然违反。
  • 错误处理,雅致的使用错误处理的思路
    • 使用抛出异常来使程序逻辑和验证错误代码隔离。
    • 使用不可控异常,一旦一底层函数声明抛出异常, 那么上层函数逐级都要修改。。。。
    • 异常要说明,堆栈不足以说明一切
    • 打包调用API,减小对厂商API的依赖,将外部API打包调用在自己的类中,这样只有一处调用,自然好修改。
    • 别返回null,用特例模式,创建一个类或者配置一个对象,用来处理特例,空对象?
    • 别传递null值。断言验证null

【迁移】Think In Java 多态学习

    1. 动态绑定与前期绑定
    2. Static对象与Final对象不能覆盖,private 对象(方法的话,自动属于final)也不能进行覆盖。
    3. 复杂对象调用构造器要遵照下面的顺序
      1. 调用基类的构造器,这个过程会递归的调用下去。
      2. 按照声明顺序调用成员的初始化方法。
      3. 调用导出类构造器主体。
    4. 协变返回类型,导出类中被覆盖的方法可以返回基类方法的返回值类型的某种导出类型。
    5. 设计考虑时候优先考虑组合,而非继承
    6. 状态模式,动态的改变类型

//: polymorphism/Transmogrify.java
// Dynamically changing the behavior of an object
// via composition (the "State" design pattern).
import static net.mindview.util.Print.*;</p>

<p>class Actor {
  public void act() {}
}</p>

<p>class HappyActor extends Actor {
  public void act() { print(&quot;HappyActor&quot;); }
}</p>

<p>class SadActor extends Actor {
  public void act() { print(&quot;SadActor&quot;); }
}</p>

<p>class Stage {
  private Actor actor = new HappyActor();
  public void change() { actor = new SadActor(); }
  public void performPlay() { actor.act(); }
}</p>

<p>public class Transmogrify {
  public static void main(String[] args) {
    Stage stage = new Stage();
    stage.performPlay();
    stage.change();// 状态的改变
    stage.performPlay();
  }
} /* Output:
HappyActor
SadActor
*/

    1. 如果必须要执行清理,清理的顺序需要和声明顺序是相反的, 这样的话。
    2. 多态中潜藏的问题

//: polymorphism/PolyConstructors.java
// Constructors and polymorphism
// don't produce what you might expect.
import static net.mindview.util.Print.*;</p>

<p>class Glyph {
  void draw() { print(&quot;Glyph.draw()&quot;); }
  Glyph() {
    print(&quot;Glyph() before draw()&quot;);
    draw();// 执行这个方法时候,调用的其实是被覆盖以后的方法
    print(&quot;Glyph() after draw()&quot;);
  }
}</p>

<p>class RoundGlyph extends Glyph {
  private int radius = 1;//执行这一步以前, 会先执行父类的构造器, 然后父类的构造器又会直接调用覆盖以后的方法
  RoundGlyph(int r) {
    radius = r;
    print(&quot;RoundGlyph.RoundGlyph(), radius = &quot; + radius);
  }
  void draw() {
    print(&quot;RoundGlyph.draw(), radius = &quot; + radius);
  }
}</p>

<p>public class PolyConstructors {
  public static void main(String[] args) {
    new RoundGlyph(5);
  }
} /* Output:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
*/