프로그래밍/디자인패턴

디자인 패턴 - Bridge (Structural Pattern)

aiemag 2021. 2. 16. 11:45
반응형

Structural Pattern인 Bridge Pattern에 대해 정리합니다.

 


Definition

 

'기능'과 '구현'의 클래스 계층을 분리하고, 다리를 놓는 패턴

 

 

Bridge Pattern은 Structural Pattern에 해당합니다.

 


Class Diagram

기능 계층의 class는 'Abstraction' class(추상:abstraction class가 아닌 이름이 'Abstraction')입니다.

'Abstraction Class'에 기능을 추가한 것이 'RefinedAbstraction'입니다.

 

구현 계층의 class는 Implementor class와, 이를 상속하여 구현한 ConcreteImiplementor입니다.

 

Abstraction calss에서 구현 계층의 calss의 instance인 impl을 가지고 있습니다.

꼭 Object Adapter 패턴에서 Adapter가 Legacy class의 instance를 가지고 있는 것 같은 형태입니다.

하지만, 다른 class가 아니라, Abstraction class의 method의 기능을 실제 구현하는 Class의 instance를 가지고 있습니다.

 

여기서 impl instance가 기능 계층과 구현 계층의 bridge 역할을 하게 됩니다.

그리고, Implementor class는 추상:abstraction class 이며 Template Method 패턴으로 ConcreteImplementor class를 구현하여 사용합니다.

 

 

 


Sample Case

다음은 Bridge 패턴을 적용해 본 시나리오입니다.

 

최대한 필요한 내용만 간결하게 표현하기 위해서 최소한의 class와 method를 포함하였습니다.

 

 

Scenario

우리는 Printer를 가지고 있고 display()라는 기능을 사용자에게 제공합니다.

 

실제로 display를 하기 위해서 내부적으로 print() 기능을 설계하였고, 

 

물리적으로 ink를 뿌려 실제 출력을 처리하는 부분은 PrinterImipl 에서 spreadInk()로 처리를 합니다.

 

Point) 이제 물리적인 처리인 spreadInk()의 구현 내용이 변경 되더라도 Printer의 기능 interface는 신경 쓸 필요가 없습니다.

 

Point) 또한 새로운 프린터인 NewPrinter를 개발하였는데, 동일한 text를 여러번 반복하여 출력하는 기능을 추가하였습니다.

기존의 impl 메소드인 spreadInk()을 그대로 사용하고, 반복해서 출력해주는 displayMulti()라는 기능만 추가하여 NewPrinter를 개발하는 시간이 단축되었습니다!

 

 

Class Diagram

 

Printer 와 이를 상속한 NewPrinter는 "기능 계층"의 class이고,

PrinterImpl은 "구현 계층"의 abstraction class입니다. 

StringPrinterImpl은 PrinterImpl을 상속받아 method를 구현한 Template Method 패턴을 따릅니다.

 

Printer class의 impl은 PrinterImpl의 instance로써, '기능'과 '계층' class 간에 brdige 역할을 합니다.

 

 

 

Code

 

1
2
3
4
5
6
7
8
9
10
public class Main {
 
    public static void main(String[] args) {
        Printer p = new Printer(new StringPrinterImpl("printer test"));
        p.display();
        
        NewPrinter np = new NewPrinter(new StringPrinterImpl("new printer test"));
        np.displayMulti(5);
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Printer {
    
    private PrinterImpl impl;
    
    public Printer(PrinterImpl impl) {
        this.impl = impl;
    }
    
    protected void print() {
        impl.spreadInk();
    }
    
    public void display() {
        print();
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
public class NewPrinter extends Printer{
    
    public NewPrinter(PrinterImpl impl) {
        super(impl);
    }
    
    public void displayMulti(int count) {
        for(int i=0 ; i<count ; i++) {
            print();
        }
    }
}
cs

 

1
2
3
4
public abstract class PrinterImpl {
    
    public abstract void spreadInk();
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
public class StringPrinterImpl extends PrinterImpl{
    
    private String string;
    
    public StringPrinterImpl(String string) {
        this.string = string;
    }
    
    public void spreadInk() {
        System.out.println(string);
    }
}
cs

 

실행 결과입니다.

 

반응형