用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;
}

  使用低耦合的实现方式将不变的代码和易变的代码隔离,在添加新功能时,无需再改动原有的函数,更加安全和高效。

猜你喜欢

转载自blog.csdn.net/qq704072809/article/details/109410447