Course contentsShow
← Rust
Lesson 648 of 1,9105. Type System and TraitsFree lesson

The Bridge Pattern for Platform Ports

Separate abstractions from implementations to easily port systems across hardware.

In this lesson, you will learn how to decouple your business logic from hardware-specific code by using the Bridge Pattern to create flexible, portable systems.

When building applications that run on multiple platforms (like an embedded sensor, a desktop PC, or a web browser), you often face a problem: your core logic becomes tangled with platform-specific hardware calls. If you write your logic directly against the hardware, you’ll be forced to rewrite it every time you port your code to a new device.

The Bridge Pattern solves this by splitting your code into two distinct layers:

  1. The Abstraction: This represents the "what"—the high-level operations your application performs (e.g., turn_on(), measure_temp()).
  2. The Implementation: This represents the "how"—the low-level, hardware-specific code that actually executes those operations.

In Rust, we achieve this by defining a trait for the implementation. The abstraction holds a reference to a type that implements that trait.

// The Implementation Interface (The "How")
trait HardwareDriver {
    fn send_signal(&self, value: u8);
}

// The Abstraction (The "What")
struct DeviceController<T: HardwareDriver> {
    driver: T,
}

impl<T: HardwareDriver> DeviceController<T> {
    fn power_up(&self) {
        // High-level logic stays the same regardless of hardware
        self.driver.send_signal(1);
    }
}

By using this approach, your DeviceController doesn't need to know if it's talking to an ArduinoDriver, a LinuxDriver, or a MockDriver used for unit testing. You simply swap the struct that implements the HardwareDriver trait during initialization.

Because the abstraction and implementation are connected via a trait rather than a concrete type, you can ship your business logic as a crate and let users provide their own platform-specific implementation. This keeps your system modular and prevents hardware-specific "leaks" from polluting your core logic.

Key Takeaway: Use the Bridge Pattern to separate high-level domain logic from low-level platform code, allowing you to swap hardware implementations without touching your core application.