- 개요
- 추상화 부분과 구현 부분을 분리시켜 서로 독립적으로 확장 가능하게 한다. (Decouple an abstraction from its implementation so that the two can vary independently)
- 아래의 Class Digram에서 추상화 부분은 AProgram, Program 부분이고 구현 부분은 Aalgorithm, Algorithm1, Algorithm2 부분이다. Client는 추상화 부분만 알게되고 실제적으로 내부구현 부분이 있는 구현 부분에 대해서는 모르게 된다. 따라서 구현 부분이 바뀌어도 Client에 제공되는 추상화 interface 부분은 변경이 없다.
- ProgramA와 ProgramB가 Algorithm1이나 Algorithm2에 따라서 다르게 동작하는 경우(리모콘이 있는데 여러 TV제품사 별로 채널변경하는 기능이 다른 경우, SearchEngine이 있는데 OS별로 Search방법이 다른 경우)에 client에게 interface를 담당하는 Program부분과 실제로 처리하는 로직 및 비즈니스를 구현하는 Algorithm를 서로 분리해서 독립적으로 확장 가능하게 한다. 만약 이런 구조가 아니면 AProgram을 구현하는 Algorithm1ProgramA, Algorithm2ProgramB와 같이 구현되는 형태가 되므로 class들이 많이 증가하게 되므로 추가 및 수정에 용이하지 않다.
- 문제 예
- 소스
public abstract class Aalgorithm {
abstract int calculate(int num);
}
public class Algorithm1 extends Aalgorithm {
int calculate(int num) {
return (num + 2) * 10;
}
}
public class Algorithm2 extends Aalgorithm {
int calculate(int num) {
return (num - 1) + 200 * 123;
}
}
public abstract class AProgram {
int num = 0;
Aalgorithm algorithm = null;
public AProgram(int num, Aalgorithm algorithm) {
this.num = num;
this.algorithm = algorithm;
}
public abstract int cal();
}
public class Program extends AProgram {
public Program(int num, Aalgorithm algorithm) {
super(num, algorithm);
}
public int cal() {
return this.algorithm.calculate(this.num);
}
}
public class Client {
public static void main(String[] args) {
AProgram prog1 = new Program(2, new Algorithm1());
AProgram prog2 = new Program(5, new Algorithm2());
int result1 = prog1.cal();
int result2 = prog2.cal();
System.out.println("result1[" + result1 + "]");
System.out.println("result2[" + result2 + "]");
}
}
-------------------------
result1[40]
result2[24604]
- 구현 관련
- Program 부분을 Template Class 형태로 변경하면 Client에서 다음과 같이 사용할 수도 있다. (아래의 '위키피디아' 링크의 내용 중 '이름을 사용한 c#'부분의 내용 참고)
- AProgram prog1 = new Program<Algorithm1>(2);
- AProgram prog2 = new Program<Algorithm2>(2);
- AProgram에서 다음과 같이 수정하게 되고 Program에서는 algorithm의 값을 바로 사용하는 형태가 되면, 추후 algorithm이 추가될때 마다 소스를 수정해 줘야 하는 단점이 있다. 차라리 Abstract Factory나 Factory Method를 사용해도 될것 같다.
- 변경 전 : Aalgorithm algorithm = null;
- 변경 후 :
- #ifdef _ALG1
- Aalgorithm algorithm = new Algorithm1();
- #else
- Aalgorithm algorithm = new Algorithm2();
- #end if
- Progam에서 num값이 10 이상이면 algorithm1이 실행되고, 10미만이면 algorithm2가 실행되게 사용할 수 있다.
- 차이점
- Adapter Pattern 은 이미 존재하는 객체를 이용해서 다른 객체의 인터페이스를 만들어 주기 위한 목적으로 쓰이나, Bridge패턴은 추상화 부분과 구현 부분을 분리해서 독립적으로 확장하고자 하기 위한것이다. 즉 Bridge Pattern은 분리를 할려고 하고 Adapter는 재활용 할려고 한다.
- 참고