Tuesday, January 24, 2012

The Bridge pattern

Problem: Draw rectangles and circles with either of two drawing programs without causing an explosion in the number of classes.
Solution: Decoupling implementation from the objects that use them.
public abstract class AbstractShape {
    private DrawingProgram dp;
    public abstract void draw();
    public AbstractShape(DrawingProgram dp) {
        this.dp = dp;
    }
    public void drawLine() {
        this.dp.drawLine();
    }
    public void drawCircle() {
        this.dp.drawCircle();
    }
}
public class Rectangle extends AbstractShape {
    public Rectangle(DrawingProgram dp) {
        super(dp);
    }
    @Override public void draw() {
        drawLine(); drawLine(); drawLine(); drawLine();
    }
}
public class Circle extends AbstractShape {
    public Circle(DrawingProgram dp) {
        super(dp);
    }
    @Override public void draw() {
        drawCircle();
    }
}
public interface DrawingProgram {
    void drawLine(); // implicitly public
    void drawCircle();
}
public class DrawingProgram1 implements DrawingProgram {
    @Override public void drawLine() { ... }
    @Override public void drawCircle() { ... }
}
public class DrawingProgram2 implements DrawingProgram {
    @Override public void drawLine() { ... }
    @Override public void drawCircle() { ... }
}
public class client {
    public static void main(String[] args) {
        Drawing dp1 = new DrawingProgram1();
        Rectangle rectangle = new Rectangle(dp1);
        Drawing dp2 = new DrawingProgram2();
        Circle circle = new Circle(dp2);

        circle.draw();
        rectangle.draw();
    }
}