시냅스

브릿지 패턴 Java로 구현 본문

디자인 패턴

브릿지 패턴 Java로 구현

ted k 2022. 8. 24. 14:37

Bridge Pattern

  • 기능의 계층과 구현의 계층을 분리함
  • 추상화와 구현을 분리하여 각각을 독립적으로 변경할 수 있게 함
  • 기능의 확장과 구현의 확장을 따로 계층화 함
  • 기능에 대한 여러가지 구현을 다양하게 적용할 수 있음
  • 기능과 구현이 혼자하면 상속의 관계가 복잡해짐
  • 두 계층을 분리하고 서로의 사이에 다리(Bridge)가 필요함

 

  • Abstraction (List)
    • 추상화 개념의 상위 클래스이고 객체 구현자 (Implementor)에 대한 참조자를 관리
  • RefinedAbstraction (Stack, Queue)
    • 추상화 개념의 확장된 기능을 정의
  • Implementor (AbstractList)
    • 구현 클래스에 대한 선언을 제공
    • 하위 클래스가 구현해야 하는 기능들을 선언한다.
    • Implementor와 Abstraction의 메서드 이름은 서로 다를 수 있다.
  • ConcreteImplementor (Array, LinkedList)
    • Implementor에 선언된 기능을 실제로 구현한다. 여러 구현방식의 클래스가 만들어 질 수 있다.

 

결론

  • 기능과 구현의 결합도 약하므로, 기능이 구현 방식에 얽매이지 않는다.
  • 기능의 구현 클래스를 런타임때 지정할 수도 있다.
  • 구현이 변경되더라도 기능 클래스 부분에 대한 컴파일은 필요없다.
  • 기능과 구현은 독립적이으로 확장되며, 클라이언트는 기능의 인터페이스를 사용하므로 구체적인 구현 내용은 숨길 수 있다.

 

구현

package bridge;

import java.util.ArrayList;
import java.util.LinkedList;

interface AbstractList<T> {
    public void addElement(T obj);
    public T deleteElement(int i);
    public int insertElement(T obj, int i);
    public T getElement(int i);
    public int getElementSize();
}

class ArrayImpl<T> implements AbstractList<T> {
    ArrayList<T> store = new ArrayList<T>();
    @Override
    public void addElement(T obj) {
        store.add(obj);
    }

    @Override
    public T deleteElement(int i) {
        T t = store.get(i);
        store.remove(i);
        return t;
    }

    @Override
    public int insertElement(T obj, int i) {
        store.add(i, obj);
        return i;
    }

    @Override
    public T getElement(int i) {
        return store.get(i);
    }

    @Override
    public int getElementSize() {
        return store.size();
    }
}

class LinkedListImpl<T> implements AbstractList<T> {

    LinkedList<T> store = new LinkedList<>();

    @Override
    public void addElement(T obj) {
        store.add(obj);
    }

    @Override
    public T deleteElement(int i) {
        T t = store.get(i);
        store.remove(i);
        return t;
    }

    @Override
    public int insertElement(T obj, int i) {
        store.add(i, obj);
        return i;
    }

    @Override
    public T getElement(int i) {
        return store.get(i);
    }

    @Override
    public int getElementSize() {
        return store.size();
    }
}

class List<T>{
    AbstractList<T> impl;
    public List(AbstractList<T> list) {
        impl = list;
    }
    public  void add(T obj) {
        impl.addElement(obj);
    }
    public  T get(int i) {
        return impl.getElement(i);
    }
    public  T remove(int i) {
        return impl.deleteElement(i);
    }
    public  int getSize() {
        return impl.getElementSize();
    }
}

class Queue<T> extends List<T> {
    public Queue(AbstractList<T> list) {
        super(list);
        System.out.println("Queue를 구현합니다.");
    }
    public void enQueue(T obj) {
        impl.addElement(obj);
    }
    public T deQueue() {
        return impl.deleteElement(0);
    }
}

class Stack<T> extends List<T> {
    public Stack(AbstractList<T> list) {
        super(list);
        System.out.println("Stack을 구현합니다.");
    }

    public void push(T obj) {
        impl.addElement(obj);
    }

    public T pop() {
        return impl.deleteElement(impl.getElementSize() - 1);
    }
}

public class BridgeImpl {
    public static void main(String[] args) {
        Queue<String> arrayQueue = new Queue<String>(new ArrayImpl<String>());
        arrayQueue.enQueue("aaa");
        arrayQueue.enQueue("bbb");
        arrayQueue.enQueue("ccc");
        System.out.println(arrayQueue.deQueue());
        System.out.println(arrayQueue.deQueue());
        System.out.println(arrayQueue.deQueue());
        System.out.println("=========================");
        Queue<String> linkedQueue = new Queue<String>(new LinkedListImpl<String>());
        linkedQueue.enQueue("aaa");
        linkedQueue.enQueue("bbb");
        linkedQueue.enQueue("ccc");
        System.out.println(linkedQueue.deQueue());
        System.out.println(linkedQueue.deQueue());
        System.out.println(linkedQueue.deQueue());
        System.out.println("=========================");
        Stack<String> arrayStack = new Stack<String>(new ArrayImpl<String>());
        arrayStack.push("aaa");
        arrayStack.push("bbb");
        arrayStack.push("ccc");
        System.out.println(arrayStack.pop());
        System.out.println(arrayStack.pop());
        System.out.println(arrayStack.pop());
        System.out.println("=========================");
        Stack<String> linkedStack = new Stack<String>(new LinkedListImpl<String>());
        linkedStack.push("aaa");
        linkedStack.push("bbb");
        linkedStack.push("ccc");
        System.out.println(linkedStack.pop());
        System.out.println(linkedStack.pop());
        System.out.println(linkedStack.pop());
        System.out.println("=========================");
    }
}

 

Comments