Table of contents
Open Table of contents
Intro
- 소프트웨어 설계에서 반복적으로 발생하는 문제에 대해 반복적으로 적용할 수 있는 해결 방법을 디자인 패턴 이라고 부른다.
- 디자인 패턴이 설계를 재사용하기 위한 것이라면 프레임워크 는 설계와 코드를 함께 재사용하기 위한 것이다.
디자인 패턴과 설계 재사용
소프트웨어 패턴
패턴이란 무엇인가를 논의할 때면 반복적으로 언급되는 몇 가지 핵심적인 특징이 있다.
- 패턴은 반복적으로 발생하는 문제와 해법의 쌍으로 정의한다.
- 패턴을 사용함으로써 이미 알려진 문제와 이에 대한 해법을 문서로 정리할 수 있으며, 이 지식을 다른 사람과 의사소통할 수 있다.
- 패턴을 추상적인 원칙과 실제 코드 작성 사이의 간극을 메워주며 실질적인 코드 작성을 돕는다.
- 패턴의 요점은 패턴이 실무에서 탄생했다는 점이다.
패턴은 지식 전달과 커뮤니케이션의 수단으로 활용할 수 있기 때문에 패턴에서 가장 중요한 요소는 패턴의 ‘이름’이다.
패턴 분류
- 아키텍처 패턴: 소프트웨어의 전체적인 구조를 결정하기 위해 사용하며, 미리 정의된 서브시스템들을 제공하고, 각 서브시스템들의 책임을 정의하며, 서브시스템들 사이의 관계를 조직화하는 규칙과 가이드라인을 포함한다.
- 분석 패턴
- 디자인 패턴: 정황 내에서 일반적인 설계 문제를 해결하며, 협력하는 컴포넌트들 사이에서 반복적으로 발생하는 구조를 서술한다.
- 이디엄: 특정 프로그래밍 언어에만 국한된 하위 레벨 패턴으로, 주어인 언어의 기능을 사용해 컴포넌트, 혹은 컴포넌트 간의 특정 측면을 구현하는 방법을 서술한다.
패턴과 책임-주도 설계
- 디자인 패턴의 구성요소가 클래스와 메서드가 아니라 역할과 책임이라는 사실을 이해하는 것이 중요하다.
- 패턴을 적용하기 위해서는 패턴에서 제시하는 구조를 그대로 표현하는 것이 아니라 패턴의 기본 구조로부터 출발해서 현재의 요구에 맞게 구조를 수정해야 한다는 것을 의미한다.
캡슐화와 디자인 패턴
- Strategy 패턴의 목적은 알고리즘의 변경을 캡슐화하는 것이고 이를 구현하기 위해 객체 합성을 이용한다.
- Template Method 패턴은 알고리즘을 캡슐화하기 위해 합성 관계가 아닌 상속 관계를 사용한다.
- Decorator 패턴은 객체의 행동을 동적으로 추가할 수 있게 해주는 패턴으로서 기본적으로 객체의 행동을 결합하기 위해 객체 합성을 사용한다. 선택적인 행동의 개수와 순서에 대한 변경을 캡슐화할 수 있다.
대부분의 디자인 패턴의 목적은 변경을 캡슐화함으로써 유연하고 일관성 있는 협력을 설계할 수 있는 경험을 공유하는 것이다. 디자인 패턴에서 중요한 것은 디자인 패턴의 구현 방법이나 구조가 아니다. 어떤 디자인 패턴이 어떤 변경을 캡슐화하는지를 이해하는 것이 중요하다. 그리고 각 디자인 패턴이 변경을 캡슐화하기 위해 어떤 방법을 사용하는지를 이해하는 것이 더 중요하다.
패턴은 출발점이다
디자인 패턴이 현재의 요구사항이나 적용 기술, 프레임워크에 적합하지 않다면 패턴을 그대로 따르지 말고 목적에 맞게 패턴을 수정하라. 명확한 트레이드오프 없이 패턴을 남용하면 설계가 불필요하게 복잡해지게 된다.
프레임워크와 코드 재사용
코드 재사용 대 설계 재사용
디자인 패턴은 프로그래밍 언어에 독립적으로 재사용 가능한 설계 아이디어를 제공하기 때문에 적용하기 위해서는 프로그래밍 언어의 특성에 맞춰 가공해야 하고 매번 구현 코드를 재작성해야 한다는 단점이 있다.
가장 이상적인 형태의 재사용 방법은 설계 재사용과 코드 재사용을 적절한 수준으로 조합하는 것이다.
설계를 재사용하면서도 유사한 코드를 반복적으로 구현하는 문제를 피하는 방법이 프레임워크 다.
상위 정책과 하위 정책으로 패키지 분리하기
- 의존성 역전 원칙의 관점에서 세부 사항은 ‘변경’을 의미한다.
- 이를 위해서는 변하는 것과 변하지 않는 것을 서로 분리해야 한다.
- 변하는 것과 변하지 않는 것을 서로 다른 주기로 배포할 수 있도록 별도의 배포 단위로 분리해야한다.
- 이를 위한 첫걸음은 별도의 패키지로 분리하는 것이다.
- 의존성 역전 원리에 따라 추상화에만 의존하도록 의존성의 방향을 조정하고 추상화를 경계로 패키지를 분리했기 때문에 세부 사항을 구현한 패키지는 항상 상위 정책을 구현한 패키지에 의존해야 한다.
- 의존성을 역전시킨 객체지향 구조에서는 프레임워크가 애플리케이션에 속하는 서브클래스의 메서드를 호출한다.
- 프레임워크를 사용할 경우 개별 애플리케이션에서 프레임워크로 제어 흐름의 주체가 이동한다.
- 프레임워크에서는 일반적인 해결책만 제공하고 애플리케이션에서 따라 달라질 수 있는 특정 동작은 비워둔다. (hook)