Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1798156
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: C/C++

2012-03-25 18:34:16

Replace Conditional with Visitor 用Visitor代替条件语句: 如果你有一个很大的条件语句块,每个分支对应着不同行为。Replace Conditional with Polymorphism可以解决这个问题。但是如果这样的行为会常改变,比如每个分支都是一类人吃饭。于是有几个类:老板,打工的,要饭的。每个类各自 实现“吃饭”方法。但一旦说,我们不吃饭了,我们改成喝汤。每个子类都要把“吃饭”这个方法改为“喝汤”。如果有几十个子类,就哭了。Visitor就可 以适应这种变化。每个类都有一个方法,不是吃饭,也不是喝汤,就叫“接受访问”(accept)。我们先建一个

class Visiotr {

    void visitManager(Manager);

    void visitEngineer(Engineer);

}

如此,就一个父类

class Person {

    abstract void accept(Visitor);

}

class Manager : Person {

    void accept(Vistor v) { v.visitManager(this); }

}

class Engineer : Person {

    void accept(Visitor v) {v.visitEngineer(this); }

}

这样呢, 这种Visitor模式可以这样使用:

void f(Person p) { p.accept(new EatRiceVisitor); }

如果不想吃饭了,变为喝汤,只要换一个Visitor

void f(Person p) { p.accept(new DrinkSoapVisitor); }

Visitor的好处就是需要改变行为时,只在Visitor这一个类里修改。并且可以通过加入其它Visitor的方式扩展行为。

 

Convert Dynamic to Static Construction 将动态构造转换为静态构造: 动态构造就是运行时确定对象的类型,比如Java里的Class.forName("MyClass").newInstance();这样的好处是很灵 活,坏处就是跳过了编译时的检测,而且容易造成运行时异常。如果灵活性不是你追求的,还是老老实实的静态构造:MyClass object = new MyClass。

 

Convert Static to Dynamic Construction 将静态构造转换为动态构造:如果对象的类型确实不能在编译时确定,那就用动态构造吧。

 

Extract Package 提取包:一堆为了同一目的而存在的类,可以整合成一个包。

 

Move Class 移动类:如果一个类不属于一个包,把它移到它该属于的包里。

 

Reduce Scope of Variable 缩小变量的作用域:如 果一个变量只在某个作用域里用到,就不用在更大的作用域去声明它。如果if (bCondition) { int a = 0; b = a * 5; } 可以解决问题,就不必写成 int a = 0; if (bCondition) { b = a*5; } 控制作用域可以防止变量被声明却没有被用,而且如果bCondition是false的话,可以减少一次不必要的初始化(如果是变量是对象初始化就更 费资源了);还有好处就是你可以在别的作用域声明一个同样名字的变量,而不必担心干扰已经的变量。

 

Remove Double Negative 去除双重否定:不要太相信自己和同事的智商,也不要特意去杀死别人的脑细胞。if (!isNotFound())这样的东西写出来,可能会浪费别人四分之一柱香的时间去反应。写成 if(isFound())就好了。

 

Replace Assignment with Initialization 用初始化代替赋值:int a; ...; a = 7;写成int a = 7; 可读性提高,而且不会不小心使用了一个未初始化的变量。

 

Replace Iteration with Recursion 用递归代替迭代:主要还是看程序可读性,如果迭代的代码让人很难看懂它要做什么,可以考虑用递归函数,毕竟函数还能有个名字。

 

Replace Recursion with Iteration 用迭代代替递归: 递归一般用来处理复杂的重复。如果为了求一个整数的阶而用递归,你就被鄙视了。递归会增加栈的大小,增加函数调用的开销,所以要慎用。有一种递归要做 tail recursion,就是递归函数在函数末尾调用下一个递归. f() { ......; f(); } 这种递归被认为是没有意义的,应该用迭代来代替。因为递归的精髓在于当前的变量放在栈中,在下一递归返回后,可以从栈中返回变量,继续上一次未完成的递 归。没有用到这种特性的变量就是无意义的,如tail recursion。

 

Replace Static Variable with Parameter 用参数代替静态变量: 有时函数里会使用一些静态变量写死,如果发现这个静态变量可能根据需要外在环境改变时,可以把它作为函数的一个参数传进来。void Print () { std::cout << "hello"; } => void Print(ostream) { ostream << "hello"; } 这样它不仅可以支持cout,也可以接受一个sstream.

 

Reverse Conditional 将条件取反:if-else块里,条件放if里还是else的顺序很关键。if (!isEnabled()) ... else... 可以写成 if (isEnabled()) ... else ... 这样可以减轻脑力负担。

 

Split Loop 分离循环语句:for (int i = 0; i < n; ++i) { Total(i); Average(i); } 应该把它分成两个循环 for(..) Total(i); for(...) Average(i); 是不是有点难接受?我一开始也觉得少一次循环不挺好的吗?不过拆分这个循环是有原因的。拆分后程序可读性提高,之后甚至可以用两个函数代替这两个循环。而 且现在程序performance的瓶颈基本不会是这些迭代造成的。可读性还是要放在第一位。

阅读(910) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~