When designing software systems, it is essential to have a clean and maintainable code. One way to achieve this is by decoupling abstractions, separating them from their implementation details. The Bridge Pattern is a design pattern that allows us to do this effectively. In this article, we will explore what the Bridge Pattern is and how to use it in Java.

What is the Bridge Pattern?

The Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation so that the two can vary independently. It is useful when you want to avoid a permanent binding between an abstraction and its implementation. Instead, you can create a bridge between them, which allows you to change the implementation without affecting the abstraction.

In the Bridge Pattern, you have two hierarchies: the Abstraction hierarchy and the Implementation hierarchy. The Abstraction hierarchy defines the interface for the client, while the Implementation hierarchy provides the implementation details. The Bridge acts as a link between the two hierarchies, providing a way for the client to access the implementation details indirectly.

How to Use Bridge Pattern in Java

To implement the Bridge Pattern in Java, you need to follow a few steps:

  1. Define the Abstraction hierarchy: This hierarchy should define the abstract interface that the client will use. It should be implemented by a Concrete Abstraction class that uses the Bridge to access the implementation details.

  2. Define the Implementation hierarchy: This hierarchy should provide the implementation details. It should be implemented by a Concrete Implementation class that implements the interface defined by the Abstraction hierarchy.

  3. Define the Bridge: This class acts as a link between the Abstraction and Implementation hierarchies. It should contain a reference to the implementation object and provide methods for the client to access the implementation details indirectly.

  4. Use the Bridge: Finally, you can use the Bridge to decouple the abstraction from its implementation. The client can interact with the Abstraction hierarchy through the Bridge, which will use the Concrete Implementation to provide the implementation details.

Example Code:

public interface Vehicle {
    void startEngine();
}

public class Car implements Vehicle {
    @Override
    public void startEngine() {
        System.out.println("Starting car engine.");
    }
}

public class Bike implements Vehicle {
    @Override
    public void startEngine() {
        System.out.println("Starting bike engine.");
    }
}

public abstract class VehicleType {
    protected Vehicle vehicle;

    public VehicleType(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public abstract void start();
}

public class TwoWheeler extends VehicleType {
    public TwoWheeler(Vehicle vehicle) {
        super(vehicle);
    }

    @Override
    public void start() {
        vehicle.startEngine();
    }
}

public class FourWheeler extends VehicleType {
    public FourWheeler(Vehicle vehicle) {
        super(vehicle);
    }

    @Override
    public void start() {
        vehicle.startEngine();
    }
}

public class Client {
    public static void main(String[] args) {
        Vehicle car = new Car();
        Vehicle bike = new Bike();

        VehicleType twoWheeler = new TwoWheeler(bike);
        VehicleType fourWheeler = new FourWheeler(car);

        twoWheeler.start();
        fourWheeler.start();
    }
}

In this example, we have an Abstraction hierarchy defined by the VehicleType abstract class, which is implemented by the TwoWheeler and FourWheeler classes. The Implementation hierarchy is defined by the Vehicle interface, which is implemented by the Car and Bike classes. The Bridge is formed by the VehicleType class, which contains a reference to the Vehicle object and provides a way for the client to access the implementation details indirectly.

The Bridge Pattern is a powerful tool for decoupling abstractions from their implementation details. It allows you to change the implementation without affecting the abstraction, making your code more maintainable and flexible. By following the steps outlined in this article, you can easily implement the Bridge Pattern in your Java projects.

Reference : The Bridge Pattern in Java: An Effective Approach to Decoupling Abstractions

Bridge Pattern은 디자인 패턴 중 하나로, 객체의 인터페이스와 구현을 분리하여 각각 독립적으로 변경할 수 있는 방법을 제공합니다. 객체지향 프로그래밍에서 추상화와 구현을 분리하면 유연하고 확장 가능한 코드를 작성할 수 있습니다. 이번에는 Bridge Pattern이 무엇인지, 그리고 추상화와 구현의 분리를 통해 유연하고 확장 가능한 코드를 작성하는 방법을 알아보겠습니다.

Bridge Pattern란 무엇인가?

Bridge Pattern은 구조 패턴 중 하나로, 추상화와 구현을 분리하여 시스템의 확장성과 변화에 대응하는 방법을 제공합니다. Bridge Pattern은 추상적인 부분과 구체적인 구현부분을 분리하여 각각 독립적으로 변경할 수 있는 구조를 만듭니다. 이 방법을 사용하면 추상화된 인터페이스와 구현부를 느슨하게 결합하여 시스템의 유지보수와 확장성을 향상시킬 수 있습니다.

추상화와 구현의 분리를 통한 유연한 코드 작성 방법

추상화와 구현의 분리를 통해 유연하고 확장 가능한 코드를 작성하는 방법은 다음과 같습니다.

  1. 추상화된 인터페이스를 정의합니다. 이 인터페이스는 구현부와 독립적이며, 추상화된 기능을 정의합니다.
  2. 구현부 클래스를 정의합니다. 추상화된 인터페이스를 구현하는 클래스입니다. 이 클래스는 추상화된 인터페이스와 독립적으로 변경될 수 있으며, 실제 기능을 구현합니다.
  3. 추상화된 인터페이스를 사용하는 클라이언트 클래스를 정의합니다. 이 클래스는 추상화된 인터페이스를 사용하여 기능을 수행합니다. 이 클래스는 구현부를 알 필요가 없으며, 추상화된 인터페이스를 사용하여 기능을 수행합니다.
  4. 구현부 클래스를 사용하는 클래스를 정의합니다. 이 클래스는 추상화된 인터페이스와 구현부 클래스를 함께 사용하여 기능을 수행합니다. 이 클래스는 추상화된 인터페이스와 구현부 클래스를 연결하는 역할을 합니다.

다음은 Bridge Pattern을 구현한 코드입니다.

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw Circle");
    }
}

class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw Square");
    }
}

abstract class Brush {
    protected Shape shape;

    public Brush(Shape shape) {
        this.shape = shape;
    }

    public abstract void draw();
}

class RedBrush extends Brush {
    public RedBrush(Shape shape) {
        super(shape);
    }

    @Override
    public void draw() {
        System.out.print("Draw Red ");
        shape.draw();
    }
}

class BlueBrush extends Brush {
    public BlueBrush(Shape shape) {
        super(shape);
    }

    @Override
    public void draw() {
        System.out.print("Draw Blue ");
        shape.draw();
    }
}

public class BridgePattern {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Brush redBrush = new RedBrush(circle);
        Brush blueBrush = new BlueBrush(circle);

        redBrush.draw();
        blueBrush.draw();
    }
}

위 코드에서 Shape는 추상화된 인터페이스입니다. Circle과 Square은 Shape를 구현하는 클래스입니다. Brush는 추상화된 인터페이스를 사용하는 클라이언트 클래스입니다. RedBrush와 BlueBrush는 Brush를 구현하는 클래스입니다. 이 코드에서 Brush와 Shape는 서로 독립적으로 변경될 수 있으며, Brush를 추가하거나 Shape를 추가하더라도 영향을 받지 않습니다.

Bridge Pattern을 사용하면 추상화와 구현을 분리하여 유연하고 확장 가능한 코드를 작성할 수 있습니다. 이를 통해 시스템의 유지보수와 확장성을 향상시킬 수 있습니다. Bridge Pattern을 사용하여 객체지향 프로그래밍을 하면 더 나은 코드를 작성할 수 있습니다.

Reference : Bridge Pattern: 추상화와 구현의 분리를 통해 유연하고 확장 가능한 코드 작성하기

+ Recent posts