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