본문 바로가기

Coding Note

[Design pattern] 디자인 패턴이란

- 디자인 패턴이란?

클래스 구조를 갖는 프로그래밍을 하다보면 클래스간에 구조가 짜여지고 다양한 방법으로 객체가 생성되며 관계에 따라 여러가지 형태의 행동들이 나타난다. 그런데 기초 설계가 제대로 되어있지 않은 상태로 프로그래밍이 시작된다면 얼마 못가 클래스 관계가 꼬일대로 꼬여 누더기 진흙탕 코드덩어리로 변하게된다. 엄청나게 뛰어난 사람이어서 초기 요구에 맞춰 잘 짜여진 클래스관계를 만든다 해도 요구 사항이 바뀌게되면 쉽게 대응하지 못한다. 이미 갈 때 까지 간 코드를 뒤엎는건 그만큼 큰 비용을 감수해야하는 행동이다.

 

그런데 Object oriented programming은 이게 아니지 않은가? 분명 클래스 구조의 프로그래밍을 했는데도 프로젝트가 진행되다보면 데이터의 은닉과 캡슐화, 코드의 재사용성과 확장성 등은 누더기 코드에 가려 보이지 않는다. 제대로된 OOP를 하지 못했다는 이야기이다. 그렇다면 제대로된 OOP란 무엇을 말하는것인지 의문이 생긴다. 많은 사람들이 이에대해 고민했고 프로그램의 목적이 어떻든간에 프로그램안에 클래스들이 갖는 구조에는 일정한 '형태' 혹은 '패턴' 이 존재한다는 것을 인지하기 시작했다. 이를 바탕으로 클래스간의 관계, 클래스간의 행동양식을 분류하고 각각에 대해 객체지향적인 설계를 따르는 노하우들이 차곡차곡 정리되어 객체지향적으로 합당한 클래스 설계 형태를 정립하기 시작했고 이를 클래스 디자인 패턴 이라 이름붙이게 되었다.

 

클래스 디자인 패턴은 "'이러한 상황' 이라면 '이러한 형태의 클래스 디자인'을 하는게 대게 좋더라" 라고 말해주는것이다. 프로젝트 규모가 커지고 협업 인원이 많아질수록 이러한 기준은 일을 효율적으로 처리할 수 있게 만들어준다. 하지만 주의해야한다. 표준화된 작업은 여러가지 상황을 고려하며 만들어지기 때문에 대체로 효율성이 떨어지기 마련이다. 또한 패턴간의 관계를 생각하지 못하면 설계를 복잡하게 만드는 요소가 되어버린다. 그렇기 때문에 클래스 설계자는 분류된 디자인 패턴의 사용 목적, 장단점, 강점과 약점에 대한 충분한 이해와 패턴간의 융합에 발생할 수 있는 문제점들을 확실히 예상할 수 있어야 하며 이를 바탕으로 디자인 패턴을 적용해야한다. 무분별한 패턴의 남용은 오히려 프로그램을 망치게된다.

 

 

- 클래스 디자인 원칙

디자인 패턴은 아무개의 코딩 기법이 뚝 하고 패턴으로 만들어진것이 아니다. 많은 연구자, 개발자들에 의해서 연구되고 축적된 지식이 패턴으로써 나타나는 것이다. 이들은 클래스의 설계에 아래 설명할 몇가지 중요한 원칙을 이해하고 있었는데, 이를 바탕으로 만들어진 디자인 패턴들에는 이 설계 원칙들이 녹아있는것을 볼 수 있을것이다.

 

1) Open close principle : 클래스나 모듈, 기능들에 있어서 확장에 대해서는 열려있으며 변경에 대해서는 닫혀있어야 한다.

 

2) Dependency inversion principle : 클래스들이 의존관계를 가질때, 높은 수준(클라이언트와 가까운쪽)의 모듈이 낮은 수준(시스템과 가까운쪽)의 모듈에 의존성을 가지면 안되며, 추상화된 대상이 상세화된 대상에 의존하면 안된다.

 

3) Interface segregation principle : 클라이언트는 자신이 사용하지 않는 인터페이스에 의존관계를 가지면 안된다.

 

4) Single responsibility principle : 클래스가 변경되어야 한다면 오직 하나의 원인만 용납된다.

 

5) Likov's substitution principle : 파생 클래스는 부모 클래스로 대체 가능해야 한다.

 

이러한 원칙들은 디자인 패턴 전에 온전한 클래스 설계에 필수적인 요소이므로 충분히 이해하는것이 중요하다.

 

 

- 디자인 패턴

패턴은 목적과 형태에 따라 크게 생성 패턴, 구조 패턴, 행위 패턴 으로 나눈다. 이는 어떤 상황이며 어떤 패턴이 적용될 수 있는지 판단하는데 좋은 평가항목이 된다. 세가지 큰 분류에 따라 각 패턴에 대해 설명하였다. (항목의 순서는 <Gof 디자인 패턴> 을 따랏다.)

 

# 생성패턴

Abstract Factory
Builder
Factory Method
Prototype
Singleton

 

# 구조패턴

Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy

 

# 행위패턴

Chain of Responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
Strategy (& State)
Template Method
Visitor

 

- 마치며

디자인 패턴을 사용하는데 있어서 중요하게 고려할 점이 몇 가지 있다. 패턴에 대한 설명은 이해도를 높이기 위해 분리된 것처럼 진행되지만, 패턴의 사용에 있어서는 여러 가지 패턴들이 조화롭게 섞여있는 구조를 가지게 된다는 점을 명심해야 한다.

 

만약 무분별 하게 디자인 패턴이 사용되고 패턴들이(클래스들이) 유기적으로 결합되지 못한다면 클래스 설계에 있어서 디자인 패턴은 필요악 되어버린다. 설계자는 패턴에 목메기보다는 설계원칙을 잘 생각하면서 이를 받쳐줄 검증된 방법론으로서 디자인 패턴을 고려하여야 할 것이다.

 

또 한가지는 프로그램의 구동 환경에 있다. PC 어플리케이션이라면 디자인패턴이 가져오는 퍼포먼스에 대한 결점은 큰 문제가 되지 않을 것이다. 하지만 안드로이드 같은 모바일 환경이나 임베디드 환경이라면 디자인패턴은 사치품에 지나지 않는다.

 

마지막으로 프로그램의 구동 목적이 고려되어야 한다. 구동에 큰 설계가 필요하지 않거나 명확한 클래스구조를 갖고 코드의 변경을 고려하지 않아도 된다면 디자인패턴은 쓸데없는 비용을 늘리는 요소가 된다. 그리고 게임프로그램, 서버프로그램과 같은 고성능의 실행환경을 요구하는 프로그램이라면 퍼포먼스를 낮추는 디자인패턴은 필요성에 대해 신중에 신중을 기할 필요가 있다.

'Coding Note' 카테고리의 다른 글

matrix determinant  (0) 2013.10.23
[C++] virtual inheritance  (0) 2013.06.29
[Design pattern] Visitor  (0) 2013.03.27
[Design pattern] Template method  (0) 2013.03.27
[Design pattern] Memento  (0) 2013.03.26