In the previous article, we shared about bufferevent | Embedded Network Communication Buffer Layer, where bufferevent utilizes the Strategy Pattern design, implementing polymorphic behavior through <span>struct bufferevent_ops</span>:

Different types of bufferevent (such as socket, filter, SSL) share the same set of interfaces, calling their respective implementation functions through the <span>be_ops</span> pointer.
This article will share content related to the Strategy Pattern:
Strategy Pattern
The Strategy Pattern is a type of behavioral design pattern that defines a family of algorithms, encapsulating each one as an independent object, allowing them to be interchangeable. This pattern allows the variation of algorithms to be independent of the clients that use them.

The Strategy Pattern includes the following main roles:
- Context: Holds a reference to a strategy object to call the strategy.
- Strategy Interface: Defines a common interface for all supported algorithms or behaviors.
- Concrete Strategies: Specific classes that implement the strategy interface, providing concrete algorithm implementations.
In embedded systems, this pattern is particularly suitable for:
- Communication Protocol Switching: Dynamically switching between UART/I2C/SPI
- Sensor Data Processing: Using different processing strategies for different sensor types (temperature/humidity/light)
- Power Management: Switching power consumption strategies based on power status (battery/external power)
- Control Algorithms: Dynamically switching between algorithms like PID control and fuzzy control
Strategy Pattern vs Non-Strategy Pattern:
| Feature | Strategy Pattern | Non-Strategy Pattern |
|---|---|---|
| Algorithm Extension | Adding new strategies without modifying the context | Requires modification of core logic |
| Conditional Branching | Eliminates complex switch/case statements | Contains numerous conditional branching statements |
| Code Reuse | Strategy objects can be reused in different contexts | Algorithm logic is tightly coupled with usage scenarios |
| Runtime Flexibility | Algorithms can be switched dynamically | Behavior is determined at compile time |
| Testing Complexity | Strategy objects can be tested independently | Requires simulating the entire context environment |
Embedded Application Cases
Sensor data processing: Using different processing strategies for different sensor types (temperature/humidity).
Code Implementation:

1. Context:
// Sensor Processor (Context)
typedef struct {
SensorStrategy strategy;
void* sensor_data;
} SensorProcessor;
2. Strategy Interface:
// Strategy Interface
typedef void (*SensorStrategy)(void* data);
3. Concrete Strategies:
// Temperature Sensor Strategy
void temperature_strategy(void* data) {
float* temp = (float*)data;
printf("[C] Processing temperature: %.1fC -> Calibrated: %.1fC\n",
*temp, *temp + 0.5f);
}
// Humidity Sensor Strategy
void humidity_strategy(void* data) {
int* humidity = (int*)data;
printf("[C] Processing humidity: %d%% -> Adjusted: %d%%\n",
*humidity, *humidity + 2);
}
Complete C Example:
#include
// Strategy Interface
typedef void (*SensorStrategy)(void* data);
// Temperature Sensor Strategy
void temperature_strategy(void* data) {
float* temp = (float*)data;
printf("[C] Processing temperature: %.1fC -> Calibrated: %.1fC\n",
*temp, *temp + 0.5f);
}
// Humidity Sensor Strategy
void humidity_strategy(void* data) {
int* humidity = (int*)data;
printf("[C] Processing humidity: %d%% -> Adjusted: %d%%\n",
*humidity, *humidity + 2);
}
// Sensor Processor (Context)
typedef struct {
SensorStrategy strategy;
void* sensor_data;
} SensorProcessor;
void process_sensor(SensorProcessor* processor) {
processor->strategy(processor->sensor_data);
}
int main(void) {
printf("\n--- Strategy Pattern Demo ---\n");
float temp_data = 25.3f;
int humidity_data = 45;
SensorProcessor temp_processor = {temperature_strategy, &temp_data};
SensorProcessor hum_processor = {humidity_strategy, &humidity_data};
process_sensor(&temp_processor);
process_sensor(&hum_processor);
return 0;
}

Complete C++ Example:
#include
#include
// Strategy Interface
class SensorStrategy {
public:
virtual void process() = 0;
virtual ~SensorStrategy() = default;
};
// Temperature Sensor Strategy
class TemperatureStrategy : public SensorStrategy {
public:
explicit TemperatureStrategy(float temp) : temp_(temp) {}
void process() override {
std::cout << "Processing temperature: " << temp_ << "C -> Calibrated: " << temp_ + 0.5f << "C\n";
}
private:
float temp_;
};
// Humidity Sensor Strategy
class HumidityStrategy : public SensorStrategy {
public:
explicit HumidityStrategy(int humidity) : humidity_(humidity) {}
void process() override {
std::cout << "Processing humidity: " << humidity_ << "% -> Adjusted: " << humidity_ + 2 << "%\n";
}
private:
int humidity_;
};
// Sensor Processor (Context)
class SensorProcessor {
public:
void set_strategy(std::unique_ptr strategy) {
strategy_ = std::move(strategy);
}
void process_sensor() {
if(strategy_) strategy_->process();
}
private:
std::unique_ptr strategy_;
};
int main(void) {
std::cout << "\n--- Strategy Pattern Demo ---\n";
SensorProcessor processor;
processor.set_strategy(std::make_unique(25.3f));
processor.process_sensor();
processor.set_strategy(std::make_unique(45));
processor.process_sensor();
return 0;
}
Advantages and Disadvantages
Advantages:
- Open/Closed Principle: New strategies can be introduced without modifying the context
- Elimination of Conditional Branching: Replaces complex if-else/switch statements
- Separation of Concerns: Decouples algorithm implementation from usage logic
Disadvantages:
- Increased Number of Objects: Each strategy is an independent class/object
- Client Cognitive Load: Requires understanding the differences between various strategies
- Risk of Over-Design: Simple algorithms may not require the strategy pattern
Summary of Applicability in Embedded Scenarios

end
Previous Recommendations
Essential Reading for Embedded Linux
Recommended Learning Path for Embedded Systems
A Reader’s Clear Logic in Questioning
Successful Transition from Mechanical to Embedded Systems
A Reader’s Experience in Audio and Video Direction During Job Hunting


Scan to add me on WeChat
Join the Technical Discussion Group


Share

Collect

Like

Looking