Write low coupling program in C language

Definition of coupling

  Coupling is a measure of the degree of association between modules. The degree of coupling between modules refers to the dependencies between modules. The stronger the coupling, the worse the independence.

Advantages of low coupling

  Reducing the degree of coupling between modules can reduce the influence between modules, prevent the water wave effect of "pulling the whole body" caused by modifying a certain module, and ensure the smooth progress of system design.

Implementation example

Achieve two functions:
1. Count the total number of words in a string.
2. Count the number of strings with a length greater than n.
In both functions, each word in the string needs to be processed separately.
Functional structure diagram

Ordinary implementation

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

  This method does not seem to be a problem, but if more than ten functions are added, the count_wordsfunction selection structure will become larger and larger, and modification will become troublesome.

Low coupling implementation

  Use the function pointer to call the function function instead of using the select structure (if else; switch case) to call the function.
  The function pointer type parameter uses the void*type of ctx variable as the context of the function function, that is, the return value of the function function or some parameters.
  The function pointer type return value is used to determine whether the function execution is successful.

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

  Use a low-coupling implementation method to isolate the unchanging code from the changeable code. When adding new functions, there is no need to change the original functions, which is safer and more efficient.

Guess you like

Origin blog.csdn.net/qq704072809/article/details/109410447