用C語言撰寫低耦合程式
- 耦合的定義
- 低耦合的優點
- 實作例子
- 普通的實作方式
- 低耦合的實作方式
耦合的定義
??耦合,是對模塊間關聯程度的度量, 模塊間的耦合度是指模塊之間的依賴關系,其耦合性越強,同時表明其獨立性越差,
低耦合的優點
??降低模塊間的耦合度能減少模塊間的影響,防止對某一模塊修改所引起的“牽一發動全身”的水波效應,保證系統設計順利進行,
實作例子
實作兩個功能:
1、統計字串的單詞總數,
2、統計字串中長度大于n的個數,
在這兩個功能中,都需要將字串中的每個單詞分離單獨處理,

普通的實作方式
typedef enum _parse_words_mode_t {
MODE_SUM = 0, /* 模式:統計單詞總數 */
MODE_SUM_GT, /* 模式:統計長度大于n單詞數 */
} parse_words_mode_t;
int count_words(const char* str, parse_words_mode_t mode, int len)
{
int ret = 0;
if(NULL == str || len < 0){
return FALSE;
}
bool ret = TRUE;
for (const char* iter = str; '\0' != *iter; iter++) {
/** 獲取單詞word和單詞長度word_len(省略) **/
if(MODE_SUM == mode){
ret++;
}else if(MODE_SUM_GT == mode){
if(word_len > len){
ret++;
}
}
}
return ret;
}
int main()
{
char str[64] = "Read Text, demo.kun abcdefg abcdefg";
int32_t sum_word = count_words(str, MODE_SUM, 0);
if (sum_word >= 0) {
printf("\nword num:%d\n", sum_word);
}
int32_t gt6_word = count_words(str, MODE_SUM_GT, 6);
if (gt6_word >= 0) {
printf("\ngreat 6 letter : word num:%d\n", gt6_word);
}
return 0;
}
??這個方法看上去好像沒什么問題,但如果功能增加了十多個,那么count_words函式的選擇結構就會越來越龐大,修改就會變得麻煩,
低耦合的實作方式
??使用函式指標呼叫功能函式來代替使用選擇結構(if else; switch case)呼叫函式,
??函式指標型別引數使用void*型別的ctx變數作為功能函式的背景關系,即功能函式的回傳值或一些引數,
??函式指標型別回傳值用于判斷函式執行是否成功,
typedef int bool;
#define TRUE 1
#define FALSE 0
/* 定義函式指標型別名 */
typedef bool (*on_word_t)(void* ctx, const char* word, unsigned int size);
/**
* @method parse_words
* 決議字串中的單詞
* @param {const char*} str 需要決議單詞的字串,
* @param {on_word_t} word_func 單詞處理函式指標,
* @param {void*} ctx 單詞處理函式指標的背景關系,
*
* @return {bool} 決議成功則回傳TRUE,
*/
bool parse_words(const char* str, on_word_t word_func, void* ctx) {
if(NULL == str || NULL == word_func){
return FALSE;
}
bool ret = TRUE;
for (const char* iter = str; '\0' != *iter; iter++) {
/** 獲取單詞word和單詞長度len(省略) **/
ret = word_func(ctx, word, len + 1); /* 通過函式指標呼叫功能函式 */
}
return ret;
}
/* 統計單詞總數 */
static bool words_sum(void* ctx, const char* word, unsigned int size){
if(NULL == ctx){
return FALSE;
}
int* p_count = ctx;
(*p_count)++; /* 單詞數+1 */
return TRUE;
}
/**
* @method count_word_sum
* 計算單詞總數,
* @param {const char*} str 需要計算單詞總數的字串,
*
* @return {int} 單詞總數(若計算的字串為空指標,回傳值為-1),
*/
int count_words_sum(const char* str) {
int ret = 0;
return (TRUE == parse_words(str, words_sum, &ret)) ? ret : -1;
}
/* 統計長度大于n的單詞數 */
/* count_word_sum_gt()函式內部使用的相關引數 */
typedef struct _ctx_word_sum_gt {
int count; /* 單詞數 */
const unsigned int word_len; /* 單詞長度 */
} ctx_word_sum_gt;
static bool words_sum_gt(void* ctx, const char* word, unsigned int size) {
if(NULL == ctx){
return FALSE;
}
ctx_word_sum_gt* sum_gt_ctx = ctx;
if ((size - 1) > sum_gt_ctx->word_len) { /* 長度是否大于word_len */
sum_gt_ctx->count++; /* 單詞數+1 */
}
return TRUE;
}
/**
* @method count_word_sum_gt
* 計算單詞長度大于word_len的數量,(word_len為0時為單詞總數)
* @param {const char*} str 需要計算單詞數量的字串,
* @param {int} word_len 單詞長度,
*
* @return {int} 單詞數量(若計算的字串為空指標或單詞長度小于0,回傳值為-1),
*/
int count_words_sum_gt(const char* str, int word_len) {
if(word_len < 0){
return -1;
}
ctx_word_sum_gt ret = {
.count = 0,
.word_len = word_len,
};
return (TRUE == parse_words(str, words_sum_gt, &ret)) ? ret.count : -1;
}
int main()
{
char str[64] = "Read Text, demo.kun abcdefg abcdefg";
int32_t sum_word = count_word_sum(str);
if (sum_word >= 0) {
printf("\nword num:%d\n", sum_word);
}
int32_t gt6_word = count_word_sum_gt(str, 6);
if (gt6_word >= 0) {
printf("\ngreat 6 letter : word num:%d\n", gt6_word);
}
return 0;
}
??使用低耦合的實作方式將不變的代碼和易變的代碼隔離,在添加新功能時,無需再改動原有的函式,更加安全和高效,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/200446.html
標籤:其他
上一篇:二叉樹遞回遍歷的簡易實作
