Am I using the design pattern Bridge correctly?

6

I am studying project patterns and would like to know if the following approach is correct for the bridge pattern and if you can improve it:

    
asked by anonymous 19.03.2018 / 02:00

1 answer

8

You can not know what should be done because you do not have the question, but this does not seem to make sense.

Town classes do not implement the interface. I do not know what São Paulo is doing as aggregation there, unless it's a state, but I can not see any sense in that, Osasco is not a detail of SP implementation. And I understand even less because Citizen inherits from São Paulo. Nothing makes sense to me. This looks like a heap of comics that do nothing.

It seems to me that you have found a solution and now that making a problem fit it. This does not work. Find the problem and then look for the best solution.

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

I even say something about this in Why is there 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 set a feature on 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 method is called from this class it will call the method of the class injected into this object.

In this answer in the SO 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

Soavoidhavingtwolevelsofinheritancethatisalwaysacomplicationandavoidhaving4classeswitheverythingyouneed.Yousettheclassofeachconcreteshapetothecoloritshouldhave.

AnexampleinJavaremoved 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());
    }
}

See another example .

It is like the default Adapter , but it needs to be developed with this adaptation in mind while the Adapter can be used even in classes that were not intended for this.

It is identical to the Strategy pattern, except that the latter is about behavior and Bridge is about structure of the object.

In fact, most of the patterns defined by Gang of Four are very similar in the same group.

    
19.03.2018 / 03:56