Bridge Method Design Pattern
The Bridge Pattern is a structural design pattern that separates abstraction from implementation, allowing them to vary independently. This pattern is particularly useful in embedded systems where we may have different platforms, devices, or hardware that need to be supported.
Let’s see a simple example of the Bridge Pattern in C for embedded systems:
C
#include <stdio.h> // Implementor interface // This represents the implementation interface that concrete implementors will implement typedef struct { void (*sendData)( const char *data); } Implementor; // Concrete Implementor A typedef struct { Implementor implementor; } ConcreteImplementorA; void sendA( const char *data) { printf ("Sending data using Implementor A: %s\n", data); } void initializeConcreteImplementorA(ConcreteImplementorA * this ) { this ->implementor.sendData = sendA; } // Concrete Implementor B typedef struct { Implementor implementor; } ConcreteImplementorB; void sendB( const char *data) { printf ("Sending data using Implementor B: %s\n", data); } void initializeConcreteImplementorB(ConcreteImplementorB * this ) { this ->implementor.sendData = sendB; } // Abstraction interface // This represents the abstraction interface that concrete abstractions will implement typedef struct { Implementor implementor; void (*send)( const char *data); } Abstraction; // Refined Abstraction typedef struct { Abstraction abstraction; } RefinedAbstraction; void sendData(RefinedAbstraction * this , const char *data) { printf ("Refined Abstraction is sending data: %s\n", data); this ->abstraction.implementor.sendData(data); } void initializeRefinedAbstraction(RefinedAbstraction * this , Implementor *implementor) { this ->abstraction.implementor = *implementor; this ->abstraction.send = sendData; } int main() { ConcreteImplementorA concreteImplementorA; initializeConcreteImplementorA(&concreteImplementorA); ConcreteImplementorB concreteImplementorB; initializeConcreteImplementorB(&concreteImplementorB); RefinedAbstraction refinedAbstractionA; initializeRefinedAbstraction(&refinedAbstractionA, &concreteImplementorA.implementor); refinedAbstractionA.abstraction.send("Hello from Abstraction A"); RefinedAbstraction refinedAbstractionB; initializeRefinedAbstraction(&refinedAbstractionB, &concreteImplementorB.implementor); refinedAbstractionB.abstraction.send("Hello from Abstraction B"); return 0; } |
Explanation of the above Code:
- Implementor is an interface that declares the operations that concrete implementors must implement.
- ConcreteImplementorA and ConcreteImplementorB are concrete implementations of the Implementor interface.
- Abstraction is an interface that declares the operations that concrete abstractions must implement.
- RefinedAbstraction is a refined abstraction that extends the abstraction interface.
- Main function demonstrates how you can use the Bridge Pattern to decouple abstractions from implementations and switch implementations dynamically.
Design Patterns for Embedded Systems in C
When working with embedded systems in C, there are so many design patterns that are particularly very useful. Many design patterns can be applied to embedded systems development in C. In this article, we will discuss design patterns for Embedded Systems in C, let’s see all of them one by one with the help of examples.
Important Topics for Design Patterns for Embedded Systems in C
- What is a Design Pattern?
- Creational Design Patterns for Embedded Systems in C
- Factory Method Design Pattern
- Object Method Design Pattern
- Opaque Method Design Pattern
- Singleton Method Design Pattern
- Structural Design Patterns for Embedded Systems in C
- Callback Method Design Patterns
- Inheritance Method Design Pattern
- Virtual API Method Design Pattern
- Other Design Patterns for Embedded System in C
- Bridge Method Design Pattern
- Concurrency Method Design Pattern
- Spinlock Method Design Pattern
- Mutex Method Design Pattern
- Conditional Method Design Pattern
- Behavioral Method Design Pattern
Contact Us