写好代码的一些基本原理

长平狐 发布于 2012/11/12 11:39
阅读 87
收藏 0


v         影响局部化原理

F      代码需要通过精心的组织和设计,这样修改某处代码的时候只会影响局部的范围

F      当修改一处代码会导致不得不修改多个文件多处地方的代码时,修改的代价就会急剧上升

F      当代码中的元素具有局部影响的时候,阅读和理解代码会容易的多

F      影响局部化是很多编程原则和设计模式的基础,例如“尽量少使用全局变量”,“用多态实现条件判断”等

 

v        减少重复代码

F      实现影响局部化的一个重要方面就是减少重复代码

F      重复性的代码使程序庞大,难以理解和维护

F      代码的重复性有时知道编码的时候才能发现

F      减少重复代码的一种方式是将程序拆分成多个不同的部分——小的语句、小的方法、小的类

F      拆分后的程序可能更加适宜应用各种设计模式

F      通过设计模式解决部分重复代码的问题

 

减少重复代码的一个例子:

下面是一个函数:

void foo(……)

{

  …………..

  …………………..

         …………………………………….………………………

  ………………………….

  ……………………………..

  ……………………

}

 

   上面红色的表示重复代码,可以使用模板减少重复代码:

如上面的代码可以修改为:

template <typename Action>

void foo(……, Action& act)

{

       ……………………….

              act.DoSomething1();

       ………………………………….

       act.DoSomething2();

}

 

v      逻辑和数据放在一起

F      将数据和处理它的逻辑放在一起是影响局部化的另一个重要方面

F      通常我们使用类将数据及逻辑组织在一起

 

v      对称性

F      对称应在程序中处处体现,add()函数通常会伴随有remove()函数;孩子对象通常会被同一个父亲对象创建和销毁;围绕同一个功能的数据对象具有相同的生命周期……

F      程序中的对称是概念上的

 

比如下面的代码在对称性方面做得不太好

 

void process() {

input(); // 输入数据

// 计数器递增,明显这里的计数器递增和上面的输入函数和下面的输出函数不在

// 同一个层次上,显得极不对称

count++;

output(); // 输出结果

}

 

我们可以把上面的代码修改如下:

void process() {

    input();

    incrementCount();

    output();

}

 

    上面貌似实现对称了,但是做得还是不够好,为什么呢?

因为input函数和output已经把实现细节隐藏了,而incrementCount很明显就是告诉我们计数器加一。想到这里,我们可以做得更好:

void process() {

    input();

    tally(); // 这里tally是记录的意思

    output();

}

v      声明性表达

F      尽可能的通过声明的方式表达自己的意图

F      基于过程的,命令式的表达迫使程序阅读者在大脑中建立一条执行线路并且随着代码而思考

F      声明性表达没有执行序列和条件判断,更加容易阅读和理解

F      典型的声明性语言:SQL——只描述要得到什么,并不描述如何得到

F      在C++中,通过宏可以将重复性的执行序列转化为表达式的声明

 

一般人认为宏会降低代码的可读性(对此我也有同感,以前我看《深入浅出MFC》,一开始看到前几章遍布宏就感到头痛),但是我们常常可以看到一些大师写的代码都带有一些宏。C++中通过宏实现声明性表达不但可以减少重复性的代码,还使代码的理解和使用非常容易。虽然被宏隐藏的代码可能晦涩难懂,但宏使用者一般可以不关心。

 

v      改变频率

F      将具有相同改变频率的算法逻辑和数据组织在一起

F      从数据对象角度来说,一个数据对象内部的成员应该大致以相同的频率改变

F      一个成员如果仅仅在类的某一个函数中被涉及到,那么它很可能应该是一个局部变量

F      两个成员如果总是在一起改变但是和其它成员具有差别较大的改变率,那么这个两个成员可能应该属于一个辅助对象

 

比如我们定义了一个账户类,

// 设置某一种货币的金额

void Account::setAmount(int value, String currency)

{

              this.value = value;

              this.currency = currency;

}

 

我们可以看到货币名称和金额是同时变化的,因此我们可以定义一个金钱类的对象,它由货币名称和金额组成,修改代码如下:

 

void Account::setAmount(int value, String currency)

{

              this.value = new Money(value, currency);

}

 

     我们还可以做得更好:

void Account::setAmount(Money value)

{

              this.value= value;

}

 

实际上将具有相同改变率的逻辑和数据放在一起也是对称性的表现,对影响局部化的实现也有促进作用。


作者:朱金灿

来源:blog.csdn.net/clever101

 



原文链接:http://blog.csdn.net/zhmxy555/article/details/7335055
加载中
返回顶部
顶部