Computer Science

Bridge Pattern | 브릿지 패턴

연_우리 2022. 8. 15. 00:25
반응형

목차

     

     

     

    어떤 상황에서 쓰일까?

    게임 캐릭터의 속성을 생각해보자

    스킨도 있고, 캐릭터 고유 스킬도 있고, 공통적인 캐릭터 스킬도 있고...

    이 기능과 구현들을 모두 인터페이스나 추상 클래스를 확장해서 만들 수 있을까?

    아마 implments 뒤에 붙는 인터페이스들이 20개가 넘어갈수도있다 ㅎㅎ

     

    클라이언트가 바라보는건 '캐릭터'(추상화)이고 '캐릭터'의 구체적인 스킨과 스킬(구현체들)을 연결해서 사용하자!

     

     

    다른 예시로, JDBC드라이버를 사용할 때

    DriverManager.getConnection, Statement.execute(SQL), connection.prepareStatement(SQL).. 등이 모두 추상화된 기능이고

    Class.forName("DriverName")에서 구체적인 구현체들을 가져오게된다!

     

     

    브릿지 패턴이란?

    추상적인 것과 구체적인 것을 분리하여 연결하는 패턴이다.

    크게 기능(메서드)과 구현(규약)을 클래스 계층으로 분리한 후, 계층구조로 확장해나가는 과정에서

    기능과 구현을 연결해주는 것을 브릿지 패턴이라고 한다.

     

    public static void main(String[] args) {
    	Shape tri = new Triangle(new RedColor());
    	tri.applyColor();
    
    	Shape pent = new Pentagon(new GreenColor());
    	pent.applyColor();
    }
    
    // Triangle filled with color red.
    // Pentagon filled with color green.

     

    장점

    - 추상적인 코드와 구체적인 코드를 분리하며, 구체적인 코드를 독립적으로 확장해나갈 수 있다.

     

    단점

    - 계층구조가 늘어나 복잡도가 증가한다

     

     

     

     

    구현코드

    기존코드

    public interface Champion extends Skin {
        void move();
        void skillQ();
        void skillW();
        void skillE();
        void skillR();
    }
    
    public class KDA아리 implements Champion {
        @Override public void move() { System.out.println("KDA 아리 move"); }
        @Override public void skillQ() { System.out.println("KDA 아리 Q"); }
        @Override public void skillW() { System.out.println("KDA 아리 W"); }
        @Override public void skillE() { System.out.println("KDA 아리 E"); }
        @Override public void skillR() { System.out.println("KDA 아리 R"); }
    
        @Override
        public String getName() {
            return null;
        }
    }
    public class App {
        public static void main(String[] args) {
            Champion kda아리 = new KDA아리();
            kda아리.skillQ();
            kda아리.skillR();
        }
    }

     

    여기서 스킨이 하나씩 나올때마다 동일하게.. 비슷하게 클래스가 생성될 것이다!

    챔피언의 동작 부분과 스킨 부분을 합쳐서 KDA아리 클래스를 정의하고 있어 확장이 어렵다.

     

     

     

     

    변경코드

    챔피언 동작부분과 스킨부분을 분리한다.

    public class DefaultChampion implements Champion {
    
        private Skin skin;
        private String name;
        public DefaultChampion(Skin skin, String name) {
            this.skin = skin;
            this.name = name;
        }
    
        @Override public void move() { System.out.printf("%s %s move\n", skin.getName(), this.name); }
        @Override public void skillQ() { System.out.printf("%s %s Q\n", skin.getName(), this.name); }
        @Override public void skillW() { System.out.printf("%s %s W\n", skin.getName(), this.name); }
        @Override public void skillE() { System.out.printf("%s %s E\n", skin.getName(), this.name); }
        @Override public void skillR() { System.out.printf("%s %s R\n", skin.getName(), this.name); }
    
        @Override
        public String getName() {
            return null;
        }
    }

     

    public class 아리 extends DefaultChampion {
        public 아리(Skin skin) {
            super(skin, "아리");
        }
    }
    public class KDA implements Skin{
        @Override
        public String getName() {
            return "KDA";
        }
    }
    public abstract class App implements Champion {
    
        public static void main(String[] args) {
            Champion kda아리 = new 아리(new KDA());
            kda아리.skillQ();
            kda아리.skillW();
    
            Champion poolParty아리 = new 아리(new PoolParty());
            poolParty아리.skillR();
            poolParty아리.skillW();
        }
    }

     

     

    반응형
    • 네이버 블러그 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 구글 플러스 공유하기
    • 카카오톡 공유하기