[디자인 패턴 1편]. 디자인 패턴 개요
1. 디자인 패턴이란
디자인 패턴은 소프트웨어 공학론 안의 좋은 코드를 설계하기 위한 일종의 설계 디자인 방법론이다.
그렇다면 좋은 코드란 무엇인가?
좋은 코드란, 가독성, 간결함 등 여러 방면이 있겠지만, 디자인 패턴에서는 설계적 관점에서의 좋은 코드를 말한다.
즉, 확장과 수정에 용이하여 설계 이후에도 추가적인 유지 보수에 비용이 적게들어가는 코드를 말한다.
객체지향적으로 생각하면, 추구해야할 설계 방향은 다음과 같다.
객체 간 응집도는 높이고, 결합도는 낮게.
요구 사항 변경 시, 코드 변경을 최소화 하는 방향으로.
그리고 이러한 '좋은 코드' 설계하려면 이러이러한 원칙들이 지켜지면 좋다라고 논의되어왔다.
조금 더 스코핑하면, '객체지향 방법론' 에서는 이게 SOLID 원칙이 된다.
또 이러한 원칙에 기반하여, 좀 더 구체적인 코드 설계 패턴 종류가 몇 가지로 네이밍되는데, 이게 앞으로 살펴볼 디자인 패턴이라는 것들이다.
내가 코딩을 할 때 실제로 모든 케이스가 이렇게 미리 알려진 디자인패턴에 들어맞을리는 없지만, 그래도 어느정도 '교과서' 같이 정의되고 분류된 패턴들이다. 이 패턴들로부터 다양하게 응용가능하므로, 충분히 공부해볼만 하다.
2. SOLID 원칙 (객체지향 5대 원칙)
1) SRP (Single Responsiblity Principle, 단일 책임 원칙)
- 클래스나, 함수는 단 하나의 책임(기능)만을 가져야 한다.
- 클래스, 함수가 비대해지면 이를 분리시킬 필요가 있다.
- 산탄총 수술
- 하나의 책임이 여러 개의 클래스로 분산되어 있는 경우
- 요구 사항이 변경될 시, 분산된 책임을 가지고 있는 모든 부분을 살펴야 한다.
2) OCP (Open-Closed Principle, 개방-폐쇄 원칙)
- 기존 코드 변경에는 닫혀있고, 추가나 확장에는 열려있어야 한다.
- 자주 변경될 수 있는 내용은 수정하기 쉽게 설계해야 하고,
자주 변경되지 않을 내용은 수정에 영향받지 않게 설계해야 한다.
3) LSP (Liskov Substitution Principle, 리스코프 치환 원칙)
- 자식 클래스는 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다.
- 파생 클래스를 만들 때, 이게 정말 올바른 상속의 관계를 갖는지 생각해봐야 한다.
- 대표적인 예. Rectangle, Square 클래스
4) DIP (Dependency Inversion Principle, 의존 역전 원칙)
- 의존 관계를 맺을 때, 변화하기 쉬운 것 보단 변화하기 어려운 것에 의존해야 한다.
- 변화하기 쉬운 것 = 구체적인 것 (클래스, 서브 클래스 인스턴스)
변화하기 어려운 것 = 추상적인 것 (추상 클래스, 인터페이스) - 즉,
{인터페이스 or 추상클래스} {변수 명} = {서브 클래스 인스턴스}
꼴이 되어야 한다. - 의존성 주입 (Dependency Injection) 기술
5) ISP (Interface Segregation Principle, 인터페이스 분리 원칙)
- 클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다.
- 큰 덩어리의 인터페이스들을 구체적이고 작은 단위들로 분리시킴으로써 클라이언트들이 꼭 필요한 메서드들만 이용할 수 있게 한다.
- 다시 말해, 인터페이스를 클라이언트에 특화되도록 분리시키라는 설계 원칙이다.
잠깐 환기하는 객체지향 3대 특징
캡슐화
- 객체의 필드(속성), 메소드를 하나로 묶고, 실제 구현 내용을 외부에 감추는 것
- 정보의 손상과 오용 사전 방지.
- 다른 객체와의 독립성 유지로 전체적인 코드 유지보수 및 변경에 유연
상속
- 상속이란 기존 클래스를 재사용하는 것
- 개발시간 절약, 중복 코드 감소 및 유지보수에 용이해짐
다형성
- 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 하는 것
- 구체적으로는, 부모 클래스 또는 인터페이스의 타입 변환, 오버로딩과 오버라이딩
3. 디자인 패턴의 종류
이미 알려진 디자인 패턴은 다음과 같이 23개로 나누어져있다.
이는 GoF(Gang of Four) 디자인 패턴이라고 불리며, 4명의 유명한 개발자들에 의해 고안되었다.
생성 패턴 (Creational patterns) | 구조 패턴 (Structural patterns) | 행동 패턴 (Behavioral patterns) |
---|---|---|
싱글톤 (Singleton) | 어댑터 (Adapter) | 스트레티지 (Strategy) |
팩토리 메쏘드 (Factory Methods) | 브리지 (Bridge) | 템플릿 메쏘드 (Template Meothods) |
추상 팩토리 메쏘드 (Abstract Factory Methods) | 컴퍼지트 (Composite) | 옵저버 (Observer) |
빌더 (Builder) | 데코레이터 (Decorator) | 스테이트 (State) |
프로토타입 (Prototype) | 퍼사드 (Facade) | 비지터 (Visitor) |
플라이웨이트 (Flyweight) | 커맨드 (Command) | |
프록시 (Proxy) | 인터프리터 (Interpreter) | |
이터레이터 (Iterator) | ||
미디에이터 (Mediator) | ||
메멘토 (Memento) | ||
책임 연쇄 (Chain of Responsibility) |
23개의 모든 디자인 패턴을 모두 살펴볼 수는 없고, 이 중 주요한 패턴 위주로 다음 포스팅부터 하나씩 살펴볼 예정이다.
4. UML 표기법
디자인 패턴의 설계는 기본적으로 UML 로 표기 되기 때문에, UML 보고 이해하는 법을 알아야 한다.
UML 도 종류가 많은데, 디자인 패턴에서는 클래스 다이어그램을 중심으로 이용한다.
개인적으로 이상철님 블로그가 제일 보기쉽게 정리된 듯 하다.