ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 브리지 패턴 (Bridge Pattern)
    공부/디자인 패턴 2020. 3. 8. 17:03

    브리지 패턴이란?

    브리지 패턴은 구현부에서 추상층을 분리하여 각자 독립적으로 변형 및 확장이 가능하도록 만드는 패턴입니다. 즉, 기능과 구현에 대해 두 개의 별도의 클래스로 구현합니다.


    Abstraction : 기능 계층의 최상위 클래스이며 추상 인터페이스

    RefindAbstraction : 기능 계층에서 새로운 부분을 확장한 클래스

    Implementor : Abstraction의 기능을 구현하기 위한 인터페이스 정의

    ConcreteImplementor : 실제 기능을 구현하는 클래스

    예시

    헬스장에서 운동을 하는 것으로 예시로 들어보겠습니다.

    먼저 기능 부에 운동하는 사람에 해당하는 exerciser가 존재하고 그 하위에 오직 하체만 하는 사람, 오직 상체만 하는 사람 (예시를 위해 극단적으로..)의 클래스가 있다고 가정합니다. 다음, 운동하는 사람의 추상 객체의 기능 부분을 ExerciseHandler와 분리해 구조를 설계했습니다.


    기능을 구현하기 위한 ExerciseHandler의 인터페이스는 아래와 같습니다.

    public interface ExerciseHandler {
        public void warmUp();
        public void exercise();
        public void coolDown();
    }
    


    다음 ExerciseHandler를 상속 받아 실제 기능을 구현하는 클래스인 LowerBodyMethod와 UpperBodyMethod 입니다.

    public class LowerBodyMethod implements ExerciseHandler {
        public void warmUp()
        {
            System.out.println("하체를 열심히 달군다");
        }
        public void exercise()
        {
            System.out.println("본세트를 임하여 걷지 못 할 정도로 열심히 하체를 찢는다.");
        }
        public void coolDown()
        {
            System.out.println("달군 하체를 차분히 식혀준다.");
        }
    }
    
    
    public class UpperBodyMethod implements ExerciseHandler {
        public void warmUp()
        {
            System.out.println("상체를 열심히 달군다");
        }
        public void exercise()
        {
            System.out.println("본세트를 임하여 손이 들리지 않을 정도로 열심히 상체를 찢는다.");
        }
        public void coolDown()
        {
            System.out.println("달군 상체를 차분히 식혀준다.");
        }
    }


    다음은 기능 클래스인 Exerciser 추상 클래스 입니다.

    public abstract class Exerciser {
        private ExerciseHandler exerciseHandler;
        
        public Exerciser(ExerciseHandler exerciseHandler)
        {
            this.exerciseHandler=exerciseHandler;
        }
        public void warmUp()
        {
            exerciseHandler.warmUp();
        }
        public void exercise()
        {
            exerciseHandler.exercise();
        }
        public void coolDown()
        {
            exerciseHandler.coolDown();
        }
        public abstract void start();
    }


    다음은 기능 클래스인 Exerciser 추상 클래스를 받아 확장한 OnlyLower, OnlyUpper 클래스입니다.

    public class OnlyLower extends Exerciser
    {
        public OnlyLower(LowerBodyMethod lowerBodyMethod)
        {
            super(lowerBodyMethod);
        }
    
        @override
        public void start()
        {
            System.out.println("하체충의 운동은 어떻게?");
        }
    }
    
    
    public class OnlyUpper extends Exerciser
    {
        public OnlyUpper(UpperBodyMethod upperBodyMethod)
        {
            super(upperBodyMethod);
        }
    
        @override
        public void start()
        {
            System.out.println("상체충의 운동은 어떻게?");
        }
    }


    다음은 메인 클래스입니다.

    public class Main {
        public static void main(String[] args)
        {    
            Exerciser onlyLower = new OnlyLower(new LowerBodyMethod());
            Exerciser onlyUpper = new OnlyUpper(new UpperBodyMethod());
            
    
            onlyLower.start();
            onlyLower.warmUp();
            onlyLower.exercise();
    
            System.out.println("--------------");
    
            onlyUpper.start();
            onlyUpper.exercise();
            onlyUpper.exercise();
            onlyUpper.exercise();
        }
    }
    

    브리지 패턴과 어댑터 패턴의 차이점

    어댑터 패턴은 시스템의 설계가 완료된 후, 특정 요구 사항때문에 어댑터 패턴을 적용하는 반면에 브리지 패턴은 설계 진행 중에 의도적으로 적용시켜 두 레이어로 분리시키는 것입니다.

    파이썬에서..

    파이썬으로 구현하는 것은 위 자바와 크게 다르지 않습니다.

    import abc
    
    
    class ExerciseHandler(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def warm_up(self):
            pass
    
        @abc.abstractmethod
        def exercise(self):
            pass
    
        @abc.abstractmethod
        def cool_down(self):
            pass
    
    
    class LowerBodyMethod(ExerciseHandler):
        def warm_up(self):
            print('하체를 열심히 달군다')
    
        def exercise(self):
            print('본세트를 임하여 걷지 못 할 정도로 열심히 하체를 찢는다.')
    
        def cool_down(self):
            print('달군 하체를 차분히 식혀준다.')
    
    
    class UpperBodyMethod(ExerciseHandler):
        def warm_up(self):
            print('상체를 열심히 달군다')
    
        def exercise(self):
            print('본세트를 임하여 손이 들리지 않을 정도로 열심히 상체를 찢는다.')
    
        def cool_down(self):
            print('달군 상체를 차분히 식혀준다.')
    
    
    class Exerciser:
        def __init__(self, handler):
            self.handler = handler
    
        def warm_up(self):
            self.handler.warm_up()
    
        def exercise(self):
            self.handler.exercise()
    
        def cool_down(self):
            self.handler.cool_down()
    
        def start(self):
            raise NotImplementedError('내부 구현 필요함')
    
    
    class OnlyLower(Exerciser):
        def __init__(self, method):
            super().__init__(method)
    
        def start(self):
            print('하체충의 운동은 어떻게?')
    
    
    class OnlyUpper(Exerciser):
        def __init__(self, method):
            super().__init__(method)
    
        def start(self):
            print('상체충의 운동은 어떻게?')
    
    
    if __name__ == '__main__':
        only_lower = OnlyLower(LowerBodyMethod())
        only_upper = OnlyUpper(UpperBodyMethod())
    
        only_lower.start()
        only_lower.warm_up()
        only_lower.exercise()
    
        print('-------------')
    
        only_upper.start()
        only_upper.exercise()
        only_upper.exercise()
        only_upper.exercise()


    댓글