브릿지(Bridge) 패턴
디자인 패턴 ·브릿지 패턴은 추상화와 구현을 분리하여 두 개의 계층을 독립적으로 확장하고 변화시키는 디자인 패턴입니다.
이 패턴은 두 개의 계층을 연결하는 브릿지 역할을 하는 객체를 사용하여 유연성과 확장성을 강화합니다.
구성 요소
추상화(Abstraction): 추상화된 인터페이스를 정의합니다.
구현(Implementor): 실제 구현을 담당합니다.
브릿지(Bridge): 추상화 계층과 구현 계층을 연결합니다.
구현:
- 추상화 계층에서 추상화된 인터페이스를 정의합니다.
- 구현 계층에서 실제 구현을 담당하는 클래스를 생성합니다.
- 브릿지 역할을 하는 클래스를 생성하고, 추상화 계층과 구현 계층을 연결하는 메서드를 구현합니다.
- 클라이언트에서는 추상화된 인터페이스를 사용하여 구현 객체를 생성하고, 브릿지 역할을 하는 객체를 통해 구현 객체와 연결합니다.
장점
추상화 계층과 구현 계층을 독립적으로 확장할 수 있습니다.
추상화된 인터페이스를 통해 클라이언트와 구현 계층을 분리할 수 있습니다.
코드의 유연성과 확장성이 향상됩니다.
단점
어댑터 패턴을 사용하면 중간 단계인 어댑터 클래스가 추가되므로 약간의 성능 저하가 발생할 수 있습니다.
어댑터 클래스가 많아질 경우 코드 복잡성이 증가할 수 있습니다.
예시
롤 챔피언의 스킨에 따라 스킬 이펙트가 달라지는데, 브릿지 패턴을 이용해 챔피언과 스킨을 분리할 수 있다.
Abstraction
public interface Champion{
void move();
void skillQ();
void skillW();
void skillE();
void skillR();
void setSkin(Skin skin);
}
public class DefaultChampion implements Champion {
private final String name;
private Skin skin;
public DefaultChampion(String name, Skin skin) {
this.name = name;
this.skin = skin;
}
@Override
public void move() {
System.out.printf("%s %s move\n", this.name, this.skin.getName());
}
@Override
public void skillQ() {
System.out.printf("%s %s Q\n", this.name, this.skin.getName());
}
@Override
public void skillW() {
System.out.printf("%s %s W\n", this.name, this.skin.getName());
}
@Override
public void skillE() {
System.out.printf("%s %s E\n", this.name, this.skin.getName());
}
@Override
public void skillR() {
System.out.printf("%s %s R\n", this.name, this.skin.getName());
}
@Override
public void setSkin(Skin skin) {
this.skin = skin;
}
}
Implementor
public interface Skin {
String getName();
}
public class PoolParty implements Skin {
@Override
public String getName() {
return "PoolParty";
}
}
public class KDA implements Skin {
@Override
public String getName() {
return "KDA";
}
}
Bridge
public class 아리 extends DefaultChampion {
public 아리(Skin skin) {
super("아리", skin);
}
}
public class 아칼리 extends DefaultChampion{
public 아칼리(Skin skin) {
super("아칼리", skin);
}
}
public class 카이사 extends DefaultChampion{
public 카이사(Skin skin) {
super("카이사", skin);
}
}
client
class ChampionTest {
@Test
void move_test() {
new 아리(new KDA()).move();
new 아칼리(new KDA()).move();
new 카이사(new KDA()).move();
new 아리(new PoolParty()).move();
new 아칼리(new PoolParty()).move();
new 카이사(new PoolParty()).move();
}
...
}
결론
브릿지 패턴은 추상화와 구현을 분리하여 유연성과 확장성을 강화하는 디자인 패턴입니다.
추상화된 인터페이스를 통해 클라이언트와 구현 계층을 분리하고 브릿지 역할을 하는 객체를 통해 연결합니다.
그러나 브릿지 역할을 하는 객체 추가로 인한 성능 저하와 코드 복잡성에 주의해야 합니다.
예제는 이곳 에서 확인하실수 있습니다.