使用函数指针编写低耦合程序

实现例子

实现两个功能:

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);

/*
    解析字符串中的单词 
    str 需要解析单词的字符串 
    word_func 单词处理函数指针
    ctx 单词处理函数指针的上下文 
*/
bool parse_words(const char *str, on_word_t word_func, void *ctx)
{
    if(str == NULL || word_func == NULL) {
        return FALSE;
    }
  bool ret = TRUE;
  for(const char *iter = str; *iter != '\0'; iter++) {
    /* 获取单词word和单词长度len(省略) */
    ret = word_func(ctx, word, led+1);
  }
  return ret; }

/*
  统计单词个数
*/
static bool words_sum(void *ctx, const char *word, int size)
{
  if(word == NULL) {
    return FALSE;
  }
  
  int *p_count = ctx;
  *(p_count)++;

  return TRUE;
}

int count_words_sum(const char *str)
{
  int ret = 0;
  return (TRUE == parse_words(str, words_sum, &ret))? ret : -1;
}

/*
  统计长度大于n的单词个数
*/
typedef struc _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, int size)
{
  if(word == NULL) {
    return FALSE;
  }

  ctx_word_sum_gt *sum_gt_ctx = ctx;
  if((size - 1) > sum_gt_ctx->word_len) {
    sum_gt_ctx->count++;
  }
  return TRUE;
}

int count_words_sum_gt(const char *str, int word_len)
{
  if(word_len < 0) {
    reurn -1;
  }

  ctx_word_sum_gt ret = {
    .count = 0;
    .word_len = word_len;
  };

  reutrn (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_words_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;

}
 

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

 

posted @ 2020-11-04 10:22  张妖刀  阅读(39)  评论(0)    收藏  举报