Am I using the Pattern bridge design correctly?

Asked

Viewed 148 times

7

I am studying design standards and would like to know if the following approach is correct for the bridge pattern and if it has how to improve:

Padrão Bridge

1 answer

9


You can’t know what should be done because you don’t have it in the question, but it doesn’t seem to make sense.

City classes do not implement the interface. I don’t know what São Paulo is doing as an aggregation there, unless it’s a state, even though I can’t see the point, Osasco is not a detail of SP implementation. And I understand even less why Citizen inherits from São Paulo. For me none of this makes sense. It seems a heap of comics that do nothing.

It seems to me that you have found a solution and now you want to make a problem to adapt to it. It doesn’t work. Find the problem and then look for the best solution.

This pattern exists because of an object orientation deficiency. Almost all standards classified by the Gang of Four have been created for this. In a functional language would not be so complicated.

I even say something about it in Why there is no String.Toint method()?.

The default allows one class to delegate to others what to do. Instead of inheriting a feature it allows you to configure a feature in the object.

It allows the object to indicate which type will manipulate some aspect of that object. In general a dependency injection is made, so when a given method of this class is called it will call the class method injected into this object.

In that answer in the OS has a good example:

               ----Shape---
              /            \
         Rectangle              Circle
        /         \            /      \
BlueRectangle  RedRectangle BlueCircle RedCircle

It looks better this way and this is the bridge pattern:

          ----Shape---                        Color
         /            \                       /   \
Rectangle(Color)   Circle(Color)           Blue   Red

Padrão Bridge

This avoids having two levels of inheritance that is always a complicator and avoids having 4 classes with everything you need. You configure the class of each concrete shape with the color it should have.

A removed Java example from here:

class Node {
    public int value;
    public Node prev, next;

    public Node(int i) {
        value = i;
    }
}

class Stack {
    private StackImpl impl;

    public Stack( String s ) {
        if (s.equals("array")) {
            impl = new StackArray();
        } else if (s.equals("list")) {
            impl = new StackList();
        } else {
            System.out.println("Stack: unknown parameter");
        }
    }

    public Stack() {
        this("array");
    }

    public void push(int in) {
        impl.push( in );
    }

    public int pop() {
        return impl.pop();
    }

    public int top() {
        return impl.top();
    }

    public boolean isEmpty() {
        return impl.isEmpty();
    }

    public boolean isFull() {
        return impl.isFull();
    }
}

class StackHanoi extends Stack {
    private int totalRejected = 0;

    public StackHanoi() {
        super("array");
    }

    public StackHanoi(String s) {
        super(s);
    }

    public int reportRejected() {
        return totalRejected;
    }

    public void push(int in) {
        if (!isEmpty() && in > top()) {
            totalRejected++;
        }
        else {
            super.push(in);
        }
    }
}

class StackFIFO extends Stack {
    private StackImpl stackImpl = new StackList();

    public StackFIFO() {
        super("array");
    }

    public StackFIFO(String s) {
        super(s);
    }

    public int pop() {
        while (!isEmpty()) {
            stackImpl.push(super.pop());
        }
        int ret = stackImpl.pop();
        while (!stackImpl.isEmpty()) {
            push(stackImpl.pop());
        }
        return ret;
    }
}

interface StackImpl {
    void push(int i);
    int pop();
    int top();
    boolean isEmpty();
    boolean isFull();
}

class StackArray implements StackImpl {
    private int[] items;
    private int total = -1;

    public StackArray() {
        this.items = new int[12];
    }

    public StackArray(int cells) {
        this.items = new int[cells];
    }

    public void push(int i) {
        if (!isFull()) {
            items[++total] = i;
        }
    }

    public boolean isEmpty() {
        return total == -1;
    }

    public boolean isFull() {
        return total == items.length - 1;
    }

    public int top() {
        if (isEmpty()) {
            return -1;
        }
        return items[total];
    }

    public int pop() {
        if (isEmpty()) {
            return -1;
        }
        return items[total--];
    }
}

class StackList implements StackImpl {
    private Node last;

    public void push(int i) {
        if (last == null) {
            last = new Node(i);
        } else {
            last.next = new Node(i);
            last.next.prev = last;
            last = last.next;
        }
    }

    public boolean isEmpty() {
        return last == null;
    }

    public boolean isFull() {
        return false;
    }

    public int top() {
        if (isEmpty()) {
            return -1;
        }
        return last.value;
    }

    public int pop() {
        if (isEmpty()) {
            return -1;
        }
        int ret = last.value;
        last = last.prev;
        return ret;
    }
}

public class BridgeDisk {
    public static void main(String[] args) {
        Stack[] stacks = {new Stack("array"), new Stack("list"),
                new StackFIFO(), new StackHanoi()};
        for (int i=1, num; i < 15; i++) {
            for (int j=0; j < 3; j++) {
                stacks[j].push( i );
            }
        }
        Random rn = new Random();
        for (int i=1, num; i < 15; i++) {
            stacks[3].push(rn.nextInt(20));
        }
        for (int i=0, num; i < stacks.length; i++) {
            while (!stacks[i].isEmpty()) {
                System.out.print(stacks[i].pop() + "  ");
            }
            System.out.println();
        }
        System.out.println("total rejected is " + ((StackHanoi)stacks[3]).reportRejected());
    }
}

I put in the Github for future reference.

See another example.

He’s like the pattern Adapter, but it needs to be developed thinking about this adaptation while the Adapter can be used even in classes that were not designed for this.

He is "identical" to the pattern Strategy, except for the fact that the latter is about behavior and the bridge is about the structure of the object.

In fact much of the standards set by Gang of Four are very similar when in the same group.

  • The answer was very clear. As I said in the question, I’m studying the pattern mentioned, I tried to pull a real-life example because all the articles I’ve read are very similar to your example or about JDBC. Even so it was very clear and I loved knowing that GOF standards were created precisely to address a deficiency of object orientation, I will research more on.

  • Yes, but in the form made, I see no sense.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.