면접준비[프론트,백,데이터,CS]/CS 정리

[ C.S 지식 : 디자인패턴 ] 디자인 패턴 [ Design Pattern ]이란?

안다미로 : Web3 & D.S 2024. 11. 2. 15:48

 

 

 

 

 

[ C.S 지식 : 디자인패턴 ]  디자인 패턴 [ Design Pattern ]이란? 

 


 

∇ 디자인 패턴 [ Design Pattern ] 이란?

목  차

1. 디자인 패턴이란?
2. 디자인 패턴의 장점
3. 객체 지향의 특성과 설계 원칙 그리고 디자인 패턴
4. 디자인 패턴의 종류

 

 


 

 

1.디자인 패턴 [ Design Pattern ] 이란?


" 디자인 패턴 " 이란 개발을 진행하는 과정에서 발생하는  '반복적인 트러블 케이스' 들을

어떻게 해결할 것인지에 대한 해결 방안들로서, 실제 현업에서 비즈니스 요구 사항을

프로그래밍으로 처리하면서 만들어진 다양한 해결책 중에서 많은 사람들이 그 효용을 인정한 모범 사례들입니다.

 

 이러한 디자인 패턴은 

 "객체 지향 4대 특성 ( 캡슐화, 상속, 추상화, 다형성 ) 과 설계 원칙(SOLID)을 기반으로 구현됩니다.

 

 


2.디자인 패턴 [ Design Pattern ]의 장점.


 

      1. 재사용성 

           : 반복적인 문제에 대한 일반적인 해결책을 제공하므로,

            이를 재사용하여 유사한 상황에서 코드를 더 쉽게 작성 가능합니다.

 

      2. 가독성 

           : 일정한 구조로 정리하고 명확하게 작성하여 개발자가 코드를 이해하고 유지보수하기 쉽게 만듭니다.

 

      3. 유지보수성 

           : 코드를 쉽게 모듈화 할 수 있으며, 변경이 필요한 경우 해당 모듈만 수정하여 유지보수가 쉬워집니다.

 

      4. 확장성 

           : 새로운 기능을 추가하거나 변경할 때 디자인을 패턴을 활용하여,

                기존 코드를 변경하지 않고도 새로운 기능을 통합 가능합니다.

 

      5. 안정성과 신뢰성 

           : 수많은 사람들이 인정한 모범 사례로 검증된 솔루션을 제공합니다.

 


 

3. 객체 지향의 특성과 설계 원칙 그리고 디자인 패턴.


    ※ 객체 지향의 특성 [ 캡슐화, 상속, 추상화, 다형성 ] 은 객체 지향 프로그래밍을 위한 도구로,

        설계 원칙 ( SOLID )은 도구를 올바르게 사용하기 위한 방법으로 볼 수 있습니다.

 

       @ 그렇다면, 디자인 패턴을 비유한다면??

                              = > 요리의 "레시피"

 

            - >> 요리 제작 과정에 표준화된 요리법이 존재하듯이,  코드를 작성하는 것도 비슷합니다.

 

      프로그래밍을 진행하다보면, 여러 비슷한 문제 상황에 직면하게 됩니다.

          이러한 상황들에서 많은 개발자들이 고민하고 정제하고 정리해둔 표준과도 같은 설계 팬터이 "디자인 패턴"입니다.

 

          ※ 디자인 패턴은,  객체지향의 특성 중 "상속 & 인터페이스 & 합성(객체를 속성으로 사용) "을 이용합니다.

 

 


4. 디자인 패턴의 종류 [ 23가지, GoF의 디자인 패턴 ]


    ※ GoF의 디자인 패턴 23가지.

          - > 크게 생성(Creational) , 구조(Structural), 행위(Behavioral) 패턴으로 분류됩니다.

 

 

 

        ◎ 생성 패턴 [ Creational Pattern ]

 

 

               1. Singleton(싱글톤 패턴) 

                     : 하나의 클래스 인스턴스를 전역에서 접근 가능하게 하면서

                       해당 인스턴스는 한 번만 생성되도록 보장하는  패턴.

 

 

 

               2. Factory Method (팩토리 메서드 패턴 )

                     : 객체를 생성하기 위한 인터페이스를 정의하고,

                        서브클래스에서 어떤 클래스의 인스턴스를 생성할지 결정하는 패턴.

 

  

 

               3. Abstract Factory ( 추상 팩토리 패턴 )

                     : 관련된 객체들의 집합을 생성하는 인터페이스를 제공하며,

                          구체적인 팩토리 클래스를 통해 객체 생성을 추상화하는 패턴.

 

 

 

               4. Builder ( 빌더 패턴 )

                     : 복잡한 객체의 생성 과정을 단순화하고, 객체를 단계적으로 생성하며 구성하는 패턴.

               5. Prototype( 프로토타입 패턴 )

                     : 복잡한 객체의 생성 과정을 단순화하고, 객체를 단계적으로 생성하며 구성하는 패턴.

 


 

        ◎ 구조 패턴 [ Structural  Pattern ]


                 

               1. Adapter/ Wrapper Pattern( 어댑터 패턴 )

                     :인터페이스 호환성을 제공하지 않는 클래스를 사용하기 위해 레퍼(Wrapper)를 제공하는 패턴.

                          - > 특정 인터페이스를 클라이언트에서 요구하는 형태의 인터페이스에 적응 시켜주는 역할(중개인)

                          -  > 이름처럼,  한 인터페이스를 다른 인터페이스로 변환하기 위한 용도.

                             

 

                    - > Client는 Tartget 인터페이스를 사용해 메서드를 호출.

                    - > Adapter에서는 Adaptee 인터페이스를 사용해, concreateMethod 호출로 변경.

                    - > 이 때, Clinet는 중간에 Adapter가 있다는 것을 인지하지 못합니다.

 

 

               2. Bridge( 브릿지 패턴 )

                     :추상화와 구현단을 분리하여, 두 가지를 독립적으로 확장할 수 있는 패턴.

 

               3. Composite ( 컴포지트 패턴 ) 

                     : 개별 객체와 복합 객체를 동일하게 다루어, 트리 구조의 객체를 구성하는 패턴.

                          -> 폴더와 파일을 동일한 타입으로 취급하여, 구현을 단순화 시키는 것이 목적.

 

 

 

               4. Decorator(데코레이터 패턴)

                     : 객체에 동적으로 새로운 기능을 추가하여, 객체를 확장할 수 있는패턴.

 

  • Component (Interface) : 원본 객체와 장식된 객체 모두를 묶는 역할
  • ConcreteComponent : 원본 객체 (데코레이팅 할 객체)
  • Decorator : 추상화된 장식자 클래스
    • 원본 객체를 합성(composition)한 wrappee 필드와 인터페이스의 구현 메소드를 가지고 있다
  • ConcreteDecorator : 구체적인 장식자 클래스
    • 부모 클래스가 감싸고 있는 하나의 Component를 호출하면서 호출 전/후로 부가적인 로직을 추가할 수 있다.

 

 

               5. Facade(파사드 패턴)

                     : 서브 시스템을 더 쉽게 사용할 수 있도록 단순한 인터페이스를 제공하는 패턴.

                           - 새로운 서비스를 개발해야 해서,

                             서브 시스템들을 사용하고자 할 때 이를 하나로 묶어주는 역할을 하는 클래스를 만드는 것

               6. Flyweight(경량(플라이웨이트) 패턴)

                     : 공유(재사용) 가능한 객체를 통해 메모리 사용을 최적화하는 패턴.

                           - 캐시 개념을 코드로 패턴화 한 것.

                           - 자주 변하는 속성과 변하지 않는 속성으로 분리하고,

                               변하지 않는 속성을 캐시하여 재사용해 메모리 사용을 줄이는 방식.

  • Flyweight : 경량 객체를 묶는 인터페이스.
  • ConcreteFlyweight : 공유 가능하여 재사용되는 객체 (intrinsic state)
  • UnsahredConcreteFlyweight : 공유 불가능한 객체 (extrinsic state)
  • FlyweightFactory : 경량 객체를 만드는 공장 역할과 캐시 역할을 겸비하는 Flyweight 객체 관리 클래스
    • GetFlyweight() 메서드는 팩토리 메서드 역할을 한다고 보면 된다.
    • 만일 객체가 메모리에 존재하면 그대로 가져와 반환하고, 없다면 새로 생성해 반환한다
  • Client : 클라이언트는 FlyweightFactory를 통해 Flyweight 타입의 객체를 얻어 사용한다.

 

               7. Proxy(프록시(대리자) 패턴)

                     : 다른 객체에 대한 대리자(Proxy)를 제공하여, 접근제어*지연로딩 등을 구현하는 패턴.

                           - > 대상 원본 객체를 대리하여 대신 처리하게 함으로써 로직의 흐름을 제어.

 

 


        ◎ 행위 패턴 [ Behavioral  Pattern ]

 

               1. Observer ( 옵저버 패턴 )

                     : 객체 간의 일대다 종속 관계를 정의하여, 한 객체의 상태 변경이 다른 객체들에게 알려지도록 합니다.

                          -> 옵저버들이 관찰하고 있는 대상자의 상태가 변화가 있을 때마다 

                                  대상자는 직접 목록의 관찰자들에게 통지하고, 관찰자들은 알림을 받아서 조치를 취한느 행동 패

 

 

               2. Strategy( 전략 패턴 )

                     :  알고리즘을 정의하고, 실행 중에 선택 가능하도록 합니다.

                            - > 실행(런타임) 중에 알고리즘 전략을 선택하여, 객체 동작을 실시간으로 바뀌도록 할 수 있게 함

 

 

               3. Command( 커맨드 패턴 )

                     :  요청을 객체로 캡슐화하여 요청을 '매개변수화' 하고, 요청을 큐(Que)에 저장하거나 로깅하고 실행을 지연

                             - > 실행될 기능을 캡슐화함으로써 주어진 여러 기능들을 실행할 수 있는 재사용성이 높은 클래스 설계.

                                    -> 이벤트 발생 시 실행될 기능이 다양하면서도 변경이 필요한 경우에

                                              이벤트를 발생시키는 클래스를 변경하지 않고 재사용하고자 하는 경우

 

               4. State( 상태 패턴 )

                     :  객체의 상태를 캡슐화하고, 상태 전환을 관리합니다.

                              @상태란 : 객체가 가질 수 있는 어떤 조건이나 상황을 의미.

                         -> 체가 특정 상태에 따라 행위를 달리하는 상황에서,

                                상태를 조건문으로 검사해서 행위를 달리하는 것이 아닌, 

                                  상태를 객체화 하여 상태가 행동을 할 수 있도록 위임하는 패턴

 

  • State 인터페이스 : 상태를 추상화한 고수준 모듈.
  • ConcreteState : 구체적인 각각의 상태를 클래스로 표현. State 역할로 결정되는 인터페이스(API)를 구체적으로 구현한다. 다음 상태가 결정되면 Context에 상태 변경을 요청하는 역할도 한다.
  • Context : State를 이용하는 시스템. 시스템 상태를 나타내는 State 객체를 합성(composition)하여 가지고 있다. 클라이언트로부터 요청받으면 State 객체에 행위 실행을 위임한다.

 

               5. Chain of Responsibility( 책임 연쇄 패턴 )

                     :  요청을 보내는 쪽의 객체와, 이를 처리하는 객체를 분리하고 이들을 사슬처럼 연결해

                            다양한 처리자(핸들러)들 중 하나가 요청을 처리하도록 합니다.

                                  -> 요청을 받으면 각 핸들러는 요청을 처리할 수 있는지,

                                     없으면 체인의 다음 핸들러로 처리에 대한 책임을 전가합니다.

                                     한마디로 책임 연쇄라는 말은 요청에 대한 책임을 다른 객체에 떠넘긴다는 소리.

  • Handler : 요청을 수신하고 처리 객체들의 집합을 정의하는 인터페이스
  • ConcreteHandler : 요청을 처리하는 실제 처리 객체
    • 핸들러에 대한 필드를 내부에 가지고 있으며 메서드를 통해 다음 핸들러를 체인시키고 다음  바라본다. 
    • 자신이 처리할 수 없는 요구가 나오면 바라보고 있는 다음 체인의 핸들러에게 요청을 떠넘긴다.
    • ConcreteHandler1 - ConcreteHandler2 - ConcreteHandler3 - ... 이런식으로 체인 형식이 구성되게 된다.
  • Client : 요청을 Handler 전달한다

 

 

 

 

               6. VIsitor( 방자 패턴 )

                     :  객체 구조를 순회하면서, 다양한 연산을 수행.

               7. Interpreter ( 인터프리터 패턴 )

                     :  언어나 문법에 대한 해석기를 제공하여, 주어진 언어로 표현된 문제를 해결하는 패턴.

                            -> 자주 등장하는 문제를 간단한 언어로 정의하고 재사용하는 패턴

 

               8. Memento ( 메멘토 패턴 )

                     :  객체의 내부 상태를 외부에 저장하고 저장된 상태를 다시 복원할 수 있는 기능을 제공하는 패턴.

                            - > 객체의 모든 정보를 외부로 누출시키지 않고 캡슐화를 지킬 수 있음.

 

 

 

               9. Mediator ( 중재자 패턴 )

                     :  객체 간의 상호 작용을 캡슐화하여, 객체 간의 직접적인 통신을 방지하는 패턴.

 

 

               10. Template Method ( 템플릿 메서드 패턴 )

                     :  여러 클래스에서 공통으로 사용하는 메서드를 템플릿화하여서 상위 클래스에서 정의하고,

                                 하위 클래스마다 세부 동작 사항을 다르게 구현하는 패턴.

 

                              - > 변하지 않는 기능(템플릿)은 상위 클래스에 만들어두고

                                     자주 변경되며 확장할 기능은 하위 클래스에서 만들도록 하여서

                                  상위의 메소드 실행 동작 순서는 고정하면서 세부 실행 내용은 다양화 될 수 있는 경우에 사용.

 

                             - > 상속이라는 기술을 극대화하여, ' 알고리즘의 뼈대 '를 맞추는 것에 초점을 둡니다.

                         

  • AbstractClass(추상 클래스) : 템플릿 메소드를 구현하고, 템플릿 메소드에서 돌아가는 추상 메소드를 선언한다. 이 추상 메소드는 하위 클래스인 ConcreteClass 역할에 의해 구현된다.
  • ConcreteClass(구현 클래스) : AbstractClass를 상속하고 추상 메소드를 구체적으로 구현한다. ConcreteClass에서 구현한 메소드는 AbstractClass의 템플릿 메소드에서 호출된다.

 

 

 

               11. Iterator ( 반복자(이터레이터)  패턴 )

                     :  일련의 데이터 집합에 대하여 '순차적인 접근(순회)' 를 지원하는 패턴

 

                             @데이터 집합이란 : 객체들을 그룹을 묶어서 자료의 구조를 취하는 컬렉션

                                      ex) 리스트, 트리, 그래프, 테이블 등등..

 

                             - 복잡하게 얽혀있는 자료 컬렉션들을 순회하는 알고리즘 전략을 정의하는 것 = 이터레이터 패턴.

                          - 컬렉션 안에 들어있는 모든 원소들에 대한 접근 방식이 공통이라면

                         어떤 종류의 컬렉션에서도 이터레이터만 뽑아내면 여러 전략으로 순회가 가능하여 다형적인 코드 가능

  • Aggregate (인터페이스) : ConcreateIterator 객체를 반환하는 인터페이스를 제공한다.
    • iterator() : ConcreateIterator 객체를 만드는 팩토리 메서드
  • ConcreateAggregate (클래스) : 여러 요소들이 이루어져 있는 데이터 집합체
  • Iterator (인터페이스) : 집합체 내의 요소들을 순서대로 검색하기 위한 인터페이스를 제공한다.
    • hasNext() : 순회할 다음 요소가 있는지 확인 (true / false)
    • next() : 요소를 반환하고 다음 요소를 반환할 준비를 하기 위해 커서를 이동시킴
  • ConcreateIterator (클래스) : 반복자 객체
    • ConcreateAggregate가 구현한 메서드로부터 생성되며, ConcreateAggregate 의 컬렉션을 참조하여 순회한다.
    • 어떤 전략으로 순회할지에 대한 로직을 구체화 한다.