C language-"high cohesion, low coupling" programming ideas

1. Definition

High cohesion and low coupling are concepts in software engineering and are the criteria for judging the quality of design. It is mainly object-oriented design, which mainly depends on whether the cohesion of the class is high and the degree of coupling is low.

2. Concept

Coupling: also known as inter-block connection. Refers to a measure of the degree of closeness between modules in the software system structure. The closer the connection between the modules, the stronger the coupling and the worse the independence of the modules. The level of coupling between modules depends on the complexity of the interface between modules, the method of invocation and the information transmitted.

Cohesion: also known as intra-block contact. Refers to a measure of the functional strength of a module, that is, a measure of how closely the various elements within a module are combined with each other. If the elements (between names and between program segments) in a module are more closely related, the higher its cohesion.

The so-called high cohesion means that a software module is composed of highly correlated codes and is only responsible for one task, which is often referred to as the single responsibility principle.

For low coupling, the superficial understanding is: a complete system, between modules, as far as possible to make it independent. In other words, let each module complete a specific sub-function as independently as possible. The interfaces between modules should be as few and simple as possible. If the relationship between certain two modules is more complicated, it is best to consider further module division first. This facilitates modification and combination.

3. How to achieve

The C language is process-oriented and usually uses a callback method. C++ object-oriented, to achieve high cohesion and low coupling, interface technology is required.

To achieve high cohesion and low coupling, modules need to be designed:
      (1) The functions between each module must be clear;
      (2) The functions implemented between each functional module must not overlap;
      (3) No modules are allowed mutual calls;
      (4) If the inter-module calls must then allow only one-way call, i.e. a can call B, B may not be called A.

      Common form in C language (1)-function interface:

Try to avoid the use of global variables, how to transfer data between modules without using global variables? For example, in other modules (such as LED display), if you want to know the state of the button or set the state of the button, the general idea is to define a keyFlag global variable? Then both the LED display module and the key module directly operate the keyFlag, which improves the coupling between the modules;

There are many drawbacks to this. Assuming that someday the button module needs to be introduced into other projects for use, but the global button variable has been defined as keyStatus or not defined in the project, then how do we get the button status at this time? Is it troublesome to change global names or redefine global variables?

So it is enough to define two functions in the button module for external call:

u8_t  get_key_status(void)
{
    return  key_flag;
}

void  get_key_status(u8_t  flag)
{
    key_flag = flag;
}

The module that needs to know the button state only needs to call the above two functions, and does not need to care about the variable name of the button state defined in the button module, which reduces the use of global variables!

Common form in C language (2)-function pointer:

The software usually has the recording function of the background log, which is realized by the log function, and the main business is expressed by the business function:

void log()
{
	printf("Logging...\n");
}


void business()
{
	while(1)
	{
		sleep(1);
		printf("Deal Business...\n");
		log();
	}
}


int main()
{
	business();
	return 0;
}

Now we need to upgrade the background log function, how to achieve it?

The general idea is this: write another function log2, and then change log in business to log2. Isn't that enough?

But think about it, how can the main business code be easily changed? The main business code needs to be changed because of a small function. Doesn't it seem that IQ is very urgent?

To put it another way, use callbacks:

#include <stdio.h>
#include <unistd.h>
 
void log1()
{
	printf("1 Logging...\n");
}
 
void log2()
{
	printf("2 Logging...\n");	
}
 
void business( void (*f)() )
{
	while(1)
	{
		sleep(1);
		printf("Deal Business...\n");
		f();
	}
}
 
int main()
{
	business(log1);
	return 0;
}

The business function accepts a function pointer. The function pointed to by the pointer has no parameters and the return value is void, which conforms to the prototype of the log function. As long as f() in business can call the corresponding function.

When you need to use log1, pass log1 to the business, and when you want to use the upgraded log2, pass in log2.

In this way, the business function does not need to change the incoming data, but only cares about its own function. The user will let the user decide what data is passed in when the user calls it, which improves the versatility and flexibility of the function.

(PS: https://blog.csdn.net/scottly1/article/details/34074723 ; https://blog.csdn.net/Chum_yang/article/details/82835610 Thanks to these two bloggers for their thoughts and summary, because Picture time, quoted their case, thank you~~)

 

 

 

Guess you like

Origin blog.csdn.net/zwb_578209160/article/details/106429684