Unreal Track 1기 [25.01.06] - 디자인 패턴

chooha·2025년 1월 6일

TIL

목록 보기
14/60

1. 디자인 패턴이란

개발 시 반복적으로 등장하는 문제를 해결하기 위한 일반화된 솔루션

▸ 핵심 4요소

  • 패턴 이름 (name)
    각 패턴은 특정한 문제 해결 방법을 설명하는 고유한 이름을 가짐

  • 문제 (problem)
    패턴이 해결하려는 특정 상황 또는 문제를 설명

  • 해결책 (solution)
    문제를 해결하기 위한 설계나 전략을 제시
    이는 구체적인 코드가 아닌 추상적인 설명으로, 다양한 상황에 적용될 수 있음

  • 결과 (result)
    패턴 사용의 결과, 이점 및 잠재적인 단점 포함


▸ 중요성

  • 코드 재사용성 향상
    - 잘 정의된 패턴을 사용함으로써 반복적인 작업을 줄이고, 이미 검증된 솔루션을 활용하여 효율성을 높일 수 있음
    - 개발 시간을 단축 시키고, 전반적인 프로젝트 비용을 줄이는 데 기여

  • 유지보수 용이성
    - 명확하고 일관된 설계 접근 방식을 채택함으로써, 코드는 더 읽기 쉽고 이해하기 쉬워짐
    - 버그의 식별과 수정을 용이하게 하고, 시스템의 확장성과 유연성을 향상시킴

  • 팀 커뮤니케이션 개선
    - 공통된 용어와 개념을 사용함으로써, 팀원들은 더 빠르고 정확하게 아이디어를 전달하고 이해할 수 있음
    - 협업을 강화하고, 프로젝트의 진행 속도를 높이는 데 중요한 역할을 함

  • 효과적인 문제 해결
    - 각 패턴은 특정 문제 유형에 최적화된 해결책을 제공하며, 이를 통해 개발자들은 신속하게 문제에 접근할 수 있음

  • 장기적인 시스템 안정성
    - 검증된 패턴의 사용은 시스템의 장기적인 안정성과 신뢰성을 보장
    - 소프트웨어가 시간이 지남에 따라 변경되고 확장될 때 중요한 이점을 제공


▸ 기본 원칙

  • 단일 책임 원칙 (Single Responsibility Principle)
    - 각 클래스는 하나의 기능 또는 책임만을 가져야 함
    - 코드의 복잡성을 줄이고, 유지보스를 용이하게 함

  • 개방-폐쇄 원칙 (Open-Closed Principle)
    - 소프트웨어 엔티티는 확장에는 열려 있어야 하지만, 수정에는 닫혀 있어야 함
    - 기존 코드를 변경하지 않고도 시스템의 기능을 확장할 수 있도록 함

  • 리스코프 치환 원칙 (Liskov Substitution Principle)
    - 파생 클래스는 기반 클래스의 기능을 손상시키지 않으면서 대체 가능해야 함

  • 인터페이스 분리 원칙 (Interface Segregation Principle)
    - 클라이언트는 사용하지 않는 메소드에 의존하도록 강제되어서는 안됨
    - 더 작고 구체적인 인터페이스로 분리하는 것이 바람직함

  • 의존성 역전 원칙 (Dependency Inversion Principle)
    - 고수준 모듈은 저수준 모듈에 의존해서는 안되며, 둘 다 추상화에 의존해야 함


2. 유형

▸ 생성 패턴 (Creational Patterns)

객체를 생성할 때와 관련된 문제에 대한 해결책을 다룸
객체 생성과정을 보다 유연하게 만들어주며, 코드의 타이트한 결합을 방지함
ex. 공장에서 물건을 찍어내는 것 (물건-객체)

  • 싱글턴 (Singleton)
    한 클래스의 인스턴스가 오직 하나만 존재하도록 보장

  • 팩토리 메소드 (Factory Method)
    객체 생성을 서브 클래스에 위임하며, 클라이언트 코드가 특정 클래스의 인스턴스화와 분리됨

  • 추상 팩토리 (Abstract Factory)
    관련된 객체의 패밀리를 생성하기 위한 인터페이스를 제공함

  • 빌더 (Builder)
    복잡한 객체의 구축과 표현을 분리하며, 동일한 구축 과정으로 다양한 표현을 생성할 수 있음

  • 프로토타입 (Prototype)
    기존 객체를 복제하여 새로운 객체를 생성


▸ 구조 패턴 (Structual Patterns)

클래스와 객체를 조합하여 더 큰 구조를 형성하는 방법에 관한 것
여러개의 객체들의 구조를 어떻게 구성할지가 이 패턴의 주 관심사

  • 어댑터 (Adapter)
    호환되지 않는 인터페이스를 가진 클래스들이 함께 작동할 수 있도록 함

  • 브릿지 (Bridge)
    추상화와 구현을 분리하여, 독립적으로 변형될 수 있음

  • 컴포지트 (Composite)
    객체들을 트리 구조로 구성하여, 개별 객체와 복합 객체를 동일하게 취급할 수 있음

  • 데코레이터 (Decorator)
    객체에 동적으로 새로운 책임을 추가함

  • 퍼사드 (Facade)
    복잡한 시스템에 대한 간단한 인터페이스를 제공함

  • 플라이웨이트 (Flyweight)
    공유를 통해 작은 객체들의 수를 줄임

  • 프록시 (Proxy)
    다른 객체에 대한 접근을 제어하는 대리자 또는 자리표시자 역할을 함


▸ 행동 패턴(Behavioral Patterns)

객체들 사이의 통신과 책임의 분배에 초점을 맞춤
복잡한 흐름 제어를 간소화하고, 객체 간의 상호 작용을 더 효과적으로 만듦
ex. 특정 객체가 변할 때 다른 객체들에 이 상태를 어떻게 전달할지

  • 책임 연쇄 (Chain of Responsibility)
    요청을 처리할 수 있는 객체의 체인을 통해 요청을 전달함

  • 커맨드 (Command)
    요청을 객체로 캡슐화하여, 사용자 정의 요청에 따라 매개변수화할 수 있음

  • 인터프리터 (Interpreter)
    주어진 언어의 문법에 대한 표현을 정의하고, 해당 언어로 작성된 문장을 해석함

  • 이터레이터 (Iterator)
    컬렉션 내의 요소를 순차적으로 접근하는 방법을 제공

  • 중재자 (Mediator)
    객체들 간의 복잡한 통신을 조정하고 제어함

  • 메멘토 (Memento)
    객체의 상태를 이전 상태로 복원할 수 있는 방법을 제공

  • 옵저버 (Observer)
    객체의 상태 변화를 관찰하고, 이에 따라 다른 객체들이 반응할 수 있도록 함

  • 상태 (State)
    객체의 내부 상태에 따라 객체의 행동을 변경함

  • 전략 (Strategy)
    알고리즘을 객체의 행동으로 캡슐화하여, 동일한 행동을 다른 알고리즘으로 교체할 수 있음

  • 템플릿 메소드 (Template Method)
    알고리즘의 골격을 정의하고, 일부 단계를 서브클래스에서 구현하도록 함

  • 방문자 (Visitor)
    객체 구조의 요소에 대한 연산을 정의하여, 구조의 요소가 연산을 수행하도록 함


3. 적용 고려사항

▸ 유연성과 확장성

선택한 패턴이 시스템의 유연성과 확장성을 향상시키는지 평가

▸ 성능 고려

일부 패턴은 추가적인 추상화 레벨을 도입함으로써 시스템의 성능에 영향을 줄 수 있음
성능 요구사항을 고려하여 패턴을 적용해야 함

▸ 복잡성 관리

패턴은 문제 해결의 명확성을 제공하지만, 때로는 시스템의 복잡성을 증가시킬 수도 있음
필요 이상의 패턴 사용을 피하고, 가독성과 유지보수를 고려해야 함


4. 단점 : 한계 및 비판

▸ 과도한 사용의 위험

  • 오버 엔지니어링 (Overengineering)
    - 디자인 패턴을 필요 이상으로 사용하면, 시스템이 불필요하게 복잡해질 수 있음
    - 이는 코드의 가독성과 유지보수성을 저하시킬 수 있음

  • 적합하지 않은 상황에서의 사용
    - 모든 설계 문제에 디자인 패턴을 적용하려는 시도는 때때로 문제를 더 복잡하게 만들 수 있음
    - 패턴은 특정 문제에 대한 해결책이며, 모든 상황에 적합한 것은 아님

▸ 유연성과 성능 간의 트레이드오프

  • 추가적인 추상화 수준
    - 일부 디자인 패턴, 특히 구조적 패턴은 추가적인 추상화 레이어를 도입함
    - 이는 유연성을 향상시키지만, 동시에 시스템의 성능에 부정적인 영향을 줄 수 있음

  • 성능 저하
    - 특정 패턴, 예를 들어 싱글턴이나 플라이웨이트는 성능을 최적화하는 데 도움이 될 수 있지만, 잘못 사용될 경우 오히려 성능 저하를 초래할 수 있음

▸ 비판적 접근의 중요성

  • 상황에 따른 적용
    - 디자인 패턴은 모든 설계 문제에 대한 해결책이 될 수 없음
    - 각 패턴의 적용은 해당 문제의 맥락과 요구사항을 고려하여 신중하게 이루어져야 함

  • 지속적인 학습과 적응
    - 소프트웨어 개발 분야는 지속적으로 변화하고 있으며, 디자인 패턴 또한 새로운 기술과 방법론에 맞추어 진화해야 함
    - 개발자는 지속적으로 학습하고, 새로운 패턴을 탐색하며, 기존의 패턴을 재평가할 필요가 있음


< 참고 자료 >

디자인 패턴

0개의 댓글