Nuke Olaf - Log Store
디자인 패턴이란? 본문
나는 안드로이드 camera2 api 를 공부하다가 디자인 패턴이라는 말을 처음 들어 보았다.
카메라 객체가 "싱글톤" 객체이기 때문에 카메라 객체의 인스턴스가 한 번 생성되면, 해당 인스턴스가 반환되기 전까지는 새로운 카메라 객체를 생성할 수 없다는 내용이었다.
당시에는 기능을 구현하는게 더 중요하다고 생각했다. 그래서 왜 카메라 객체를 싱글톤 객체로 만들었는지, 디자인 패턴이 무엇인지에 대해 제대로 고민해보지 않고 넘어갔던 것 같다. 그러나 이제는 새로운 프로젝트를 시작하면서, 디자인 패턴을 공부할 수 있는 기회가 생겼다. 그래서 이제부터 디자인 패턴이란 무엇인지 공부하려고 한다.
디자인 패턴이란 무엇일까?
1. 디자인 패턴이라는 이름의 뜻
1.1 디자인 패턴의 사전적 의미
디자인 패턴이 무엇인지 알기 위해 "디자인 패턴"이라는 이름의 사전적 의미를 확인해보자.
(디자인 패턴이라는 단어 자체가 영어권 국가에서 만들어진 단어이기 때문에 영한 사전이 아닌 영영사전의 해석을 참고)
디자인 패턴은 design + pattern 두 단어의 합성어이다.
(1) design 의 사전적 의미
먼저, design 이라는 단어의 사전적 의미는 아래와 같다.
design
noun
1. a drawing or set of drawings showing how a building or product is to be made and how it will work and look
2. the art of making plans or drawings for something
3. the way in which something is planned and made
verb
1. to make or draw plans for something, for examples clothes or buildings
2. to intend
출처 : https://dictionary.cambridge.org/dictionary/english/design
즉, "디자인" 이란 무언가를 만들기 위한 계획, 또는 설계 같은것이라고 생각할 수 있겠다.
(2) pattern 의 사전적 의미
pattern 이라는 단어의 사전적 의미는 아래와 같다.
pattern
noun
1. a particular way in which something is done, is organized, or happens
2. any regularly repeated arrangement, especially a design made from repeated lines, shapes, or colours on a surface
3. something that is used as an example, expecially to copy
출처 : https://dictionary.cambridge.org/dictionary/english/pattern
즉, "패턴"이란 무언가가 행해지는 특정한 양상이며, 반복적인 형태를 띄는 무언가를 말한다고 생각할 수 있겠다.
두 단어의 사전적 의미를 종합하여 생각해보면,
디자인 패턴이란, 무언가를 만들기 위한 계획의 특정한 반복적 양상 이라고 해석이 된다.
내 해석이 맞는 것일까?
디자인 패턴은 고유명사이니 소프트웨어 공학 분야에서 디자인 패턴이 실제로 어떤 의미로 사용되는 단어인지 확인해보자.
1.2 소프트웨어 공학에서의 디자인 패턴
디자인 패턴이란 설계 문제에 대한 해결책의 재사용 가능한 형태이다.
소프트웨어 공학에서의 디자인 패턴이란,
프로그래밍을 하면서 반복적으로 발견되는 문제에 대한 반복적인 해결책이다.
" A design pattern is the re-usable form of a solution to a design problem. "
출처 : https://en.wikipedia.org/wiki/Design_pattern
" In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. A design pattern isn't a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. "
" 소프트웨어 공학에서 디자인 패턴은 소프트웨어 설계에서 흔히 발생하는 문제에 대한 일반적인 반복 가능한 해결책이다. 디자인 패턴은 코드로 직접 변환할 수 있는 완성된 디자인이 아니다. 그것은 많은 다른 상황에서 사용될 수 있는 문제를 해결하는 방법에 대한 설명이나 템플릿이다. "
출처 : https://sourcemaking.com/design_patterns
" Design patterns represent the best practices used by experienced object-oriented software developers. Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time. "
" 디자인 패턴은 경험 많은 객체 지향 소프트웨어 개발자들이 사용하는 모범 사례를 나타낸다. 디자인 패턴은 소프트웨어 개발자들이 소프트웨어 개발 과정에서 직면했던 일반적인 문제에 대한 해결책이다. 이러한 해결책은 상당한 기간 동안 수많은 소프트웨어 개발자들에 의해 시행착오를 거쳐 얻어졌다. "
출처 : https://www.tutorialspoint.com/design_pattern/design_pattern_overview.htm
1.3 디자인 패턴의 역사
디자인 패턴이라는 개념은 1966년 초 크리스토퍼 알렉산더에 의해 건축 분야에서 처음 도입되었다.
크리스토퍼 알렉산더는 반복해서 발생하는 문제와 그 문제 해결에 대한 핵심을 기술하고 싶어했다. 심지어는 비슷한 형태의 다른 문제에 있어서도 그 문제의 해결 방법에 대한 핵심내용이 재사용될 수 있도록 문서화 하기를 원했다.
그렇게해서 나오게 된 개념이 바로 "디자인 패턴" 이다.
그리고 1987년, 켄트 벡과 워드 커닝햄은 건축학에서 사용하던 디자인 패턴의 개념을 소프트웨어 공학에 적용하는 아이디어를 OOPSLA 컨퍼런스에서 발표하였다. 그리고 1994년 "Gang of Four" 에 의해 씌여진 Design Patterns: Elements of Reusable Object-Oriented Software 라는 책이 출간되면서 컴퓨터 공학분야에서 디자인 패턴이 인기를 끌기 시작했다.
2. 디자인 패턴을 사용하는 이유
2.1 검증된 솔루션을 제공한다
디자인 패턴을 설명하는 글들에서 많이 인용되는 문구가 있다.
" 바퀴를 다시 발명하지 마라 (Don't reinvent the wheel) "
즉, 이미 잘 만들어져 있고, 잘 작동되며, 잘 사용할 수 있는 것을 처음부터 다시 만들 필요가 없다는 말이다.
개발자들은 프로그램을 개발하면서 정말 많은 문제 상황을 직면한다. 문제 상황을 해결했던 방법을 잘 기억해서 비슷한 문제에 또 다시 직면했을때 그 해결책을 적용할 수 있다면 정말 유용할 것이다.
디자인 패턴은 소프트웨어를 설계할 때, 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때, 사용할 수 있는 재사용 가능한 검증된 해결책이다. 이 해결책들은 문서화가 잘 되어있으며, 이미 널리 사용되면서 입증된 안정성을 보유하고 있어 프로젝트에 대한 기술적 위험을 줄일 수 있다.
2.2 커뮤니케이션을 효율적을 만든다
"이름"이라는 개념은 생각보다 중요하다. 이름은 다른 것과 구별하기 위해 어떠한 사물, 단체, 현상 따위에 붙여서 부르는 말이다. 이름이 있으면 길게 설명해야 전달할 수 있는 개념을 한 단어로 압축하여 전달할 수 있다.
디자인 패턴은 특정 문제를 해결하는 데 사용된 패턴의 이름을 정의한다는 특징이 있다. 그래서 개발자들끼리 시스템 설계를 논의하는 과정에서 패턴의 이름을 사용하면, 특정 문제의 해결과정에 대한 개념을 길게 설명하지 않아도 되기 때문에 효율적으로 커뮤니케이션할 수 있다.
아래는 개념에 이름을 정의하는 것의 중요성에 대해 설명하는 재미있는 글이다. (더보기 클릭)
이름의 중요성
프로그래밍은 문제 해결을 위해 현실을 모사한다. 그렇기 때문에 현실을 이해하는 것은 프로그래밍을 더 잘하는 데 통찰을 줄 때가 있다. 현실의 대기열(waiting lines) 이라는 개념을 생각해보자. 은행에서 사람들은 먼저 온 순서대로 업무를 보고, 회사에서 다수가 사용하는 프린터는 먼저 입력된 데이터를 먼저 출력하며, 공유기는 먼저 도착한 패킷부터 외부 인터넷으로 송출한다.
세상에는 대기열을 사용하는 수많은 시스템과 예시가 있기 때문에 이 ‘대기열’이라는 이름 자체가 당연해보인다. 그런데 이 이름이 없다면 어떨까? 이 제도에 뚜렷이 이름이 없고 사람들 머리 속에 흐릿한 개념으로만 남아있다면?
미국 어느 엘레베이터 회사에서 일하는 Richard(이하 ‘리차드’)는 엘레베이터 이동 알고리즘을 새로 만들고 있다고 하자. 기존의 엘레베이터 작동 방식에 식상함을 느낀 그는 기존의 엘레베이터가 이동을 시작하는 층부터 시작해서 먼저 다다르는 층마다 멈추는 대신, 엘레베이터에 타는 사람들이 원하는 층을 누른 순서대로 작동하게 하려고 한다. 가령 1층에서 여러 사람들이 탔는데 그들이 버튼을 누른 순서가 ‘10, B1, 5’라면 10층을 들렀다가 지하 1층을 가고 마지막으로 5층을 가는 것이다. 이 방법이 좋은지는 정말 모르겠지만 어쨌든 이 순간에는 대기열이라는 개념이 필요하고, 이를 동료 알고리즘 설계자나 개발자들에게 공유해야 한다.
이때 이 개념을 표현하는 ‘대기열’이라는 이름이 없기 때문에 리차드는 동료들에게 자신의 구상을 다음과 같이 설명해야 할 것이다.
“이번에 말야. 기가 막힌 이동 알고리즘을 구상했다 이 말이야. 들어봐.”
“엘레베이터에 타는 사람들이 누른 층을 순서대로 저장한 뒤, 먼저 입력한 순서대로 차례대로 방문하는 방법이야.”
대기열이라는 누구나 아는 개념을 설명하기 위해 공백과 구두점 제거해도 45글자나 써야 했다. 하지만 이 개념에 ‘대기열’이라는 이름이 부여되어 있고, 이 이름을 모두가 알고 있다면 설명하는 데 얼마나 노동력을 써야 할까?
“이번에 말야. 기가 막힌 이동 알고리즘을 구상했다 이 말이야. 들어봐.”
“입력되는 층을 대기열로 저장해 이동하자.”
구체적인 개념을 쓸데없이 더 설명하지 않아도 된다. 이 얼마나 행복한지. 이렇기 때문에 이름이 중요하다. 이름이 곧 개념을 정의한다. 나는 박성환이라는 이름이 있다. 나를 아는 사람들은(이름이 공유가 된 사람들 집합에서는) 이 이름이 곧 나를 설명하는 것이다. 우리가 모든 것에 ‘이름’을 붙이는 것은 다 이유가 있는 것이다.
프로그래밍은 현실의 문제를 해결하기 위해 존재하고, 그렇기에 프로그래밍에서도 대기열이 중요하다. 대기열은 프로그래밍에서는 큐(Queue)라고 한다. 큐는 대표적인 선형적인 자료구조로, 먼저 입력된 데이터가 먼저 출력되는 FIFO(First In First Out) 자료구조다. 구체적인 대기열이 적용되는 상황을 추상화한, 현실의 개념을 추상화한 자료구조.
‘이름’이 정의되었기 때문에 자주 사용되는 개념을 구구절절 설명할 이유가 없다. 디자인 패턴도 본질적으로 이렇게 자주 사용되는 개념에 이름을 정의한 것이다.
출처 : https://shoark7.github.io/programming/knowledge/what-is-design-pattern
2.3 유지보수를 용이하게 한다
프로젝트에 디자인 패턴을 적용하면, 코드의 이해도가 높아지고 확장성이 좋아져 유지보수가 용이해진다.
애초에 소프트웨어 디자인 패턴의 핵심이 코드의 이해를 높이고, 코드의 확장성이 좋아질 수 있도록 하기 위한 해결책이기 때문이다.
2.4 객체지향 기술의 향상
디자인 패턴 자체가 OOP 패러다임에 국한된 내용은 아니다. 그러나, 디자인 패턴이라는 개념이 나올 당시에는 OOP 가 압도적인 패러다임이었다. 때문에 디자인 패턴에서 이에 대한 연구가 더 많이 진행되어 있다는 것은 부정할 수 없는 사실이다. 그래서 디자인 패턴을 찾아보면 거의 모든 내용이 OOP 패러다임에 국한된 내용들이다. 하지만 그만큼 OOP 기술에서 생길 수 있는 문제점에 대한 해결책이 거의 대부분 제시된다고 볼 수 있다.
3. 디자인 패턴의 구조
맥락 (context)
- 문제가 발생하는 여러 상황을 기술한다. 즉, 패턴이 적용될 수 있는 상황을 나타낸다.
- 경우에 따라서는 패턴이 유용하지 못한 상황을 나타내기도 한다.
문제 (problem)
- 패턴이 적용되어 해결될 필요가 있는 여러 디자인 이슈들을 기술한다.
- 이때, 여러 제약 사항과 영향력도 문제 해결을 위해 고려해야 한다.
해결 (solution)
- 문제를 해결하도록 설계를 구성하는 요소들과 그 요소들 사이의 관계, 책임, 협력 관계를 기술한다.
- 해결은 반드시 구체적인 구현 방법이나 언어에 의존적이지 않으며 다양항 상황에 적용할 수 있는 일종의 템플릿이다.
4. 디자인 패턴의 종류
1994년 GOF에 의해 씌여진 Design Patterns: Elements of Reusable Object-Oriented Software 라는 책에 의하면, 디자인 패턴에는 23가지 패턴이 존재하며 Creational, Structual, Behavior 세 가지 카테고리로 분류될 수 있다고 한다. 이 세 가지 패턴을 GoF 디자인 패턴이라고 한다. GoF 디자인 패턴은 모두 클래스와 인스턴스에 관한 생성, 구조화, 행동과 관련이 있다. 이를 통해 현재의 디자인 패턴이 객체지향에 초점을 맞추고 있다는 것을 알 수 있다.
생성 패턴 (Creational Pattern)
생성 패턴은 모두 클래스 인스턴스화에 관한 것이다.
생성패턴은 클래스 생성 패턴과 객체 생성 패턴으로 세분될 수 있다.
클래스 생성 패턴 (Class-creation patterns) 은 인스턴스 생성 시에 상속을 효과적으로 사용하는 데 집중한다.
객체 생성 패턴 (Object-creation patterns) 은 인스턴스를 효과적으로 생성하기 위해 Delegation 을 사용한다.
- Singleton : 하나의 인스턴스만 존재할 수 있는 클래스
- Factory Method : 객체 생성 처리를 서브 클래스로 분리하여 처리하도록 캡슐화하는 패턴. 클래스가 서브클래스에게 인스턴스화에 대한 책임을 전가할 수 있게 해준다
- Abstract Factory
- Builder
- Prototype
구조 패턴 (Structure Pattern)
클래스나 인스턴스들의 관계와 관련된 패턴이다. 잘 짠 프로그램은 여러 기능들이 적절히 모듈화되어 서로간에 물고 물리는 관계 속에서 동작한다. 이들의 구조를 확실히 하고, 단순하게 하여 서로간에 인터페이스를 명확히 하고 맞추는 것에 관련된 패턴이다.
- Adapter
- Composite
- Proxy
- Flyweight
- Facade
- Bridge
- Decorator
행위 패턴 (Behavior Pattern)
클래스나 인스턴스의 패턴뿐만 아니라, 이들이 동작하는 방식, 이들의 소통(Communication)방식에도 패턴을 정의한다. 이 패턴들은 객체 속 작업이 진행되는 워크 플로우를 정의하고 따라갈 수 있기 때문에 유용하다.
- Template Method : 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴
- Mediator
- Chain of Responsibility
- Observer : 한 객체의 상태 변화에 따라 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성하는 패턴
- Strategy : 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴. 같은 문제를 해결하는 여러 알고리즘이 클래스별로 캡슐화 되어 있고, 이들이 필요할 때 마다 교체할 수 있도록 함으로써 동일한 문제를 다른 알고리즘으로 해결할 수 있게 해준다
- Command
- State
- Visitor
- Iterator
- Interpreter
- Memento
J2EE 패턴
GoF 디자인 패턴 외에도 J2EE 라는 디자인 패턴이 있다. JEE 디자인 패턴은 Sun Microsystems 에 의해 개척된 반복적인 디자인 문제를 해결하기 위한 일련의 모범사례이다.
- Model View Controller
- Business Delegate
- Composite Entity
- Data Access Object
- Front Controller
- Intercepting Filter
- Service Locator
- Transfer Object
J2EE 참고 사이트 : https://stackabuse.com/java-j2ee-design-patterns/
JEE 패턴 종류 정리 : https://www.dineshonjava.com/core-j2ee-patterns-best-design-practices/
5. 디자인 패턴 사용시 주의할 점
디자인 패턴은 검증된 개발 패러다임을 제공하여 개발 프로세스를 가속화할 수 있도록 돕는다. 그러나, 몇 가지 패턴을 일종의 황금 망치로 바꾸어 모든 것에 적용하는 것은 바람직하지 않다. 소프트웨어 설계 과정에서 패턴이 해결해야하는 시나리오와 문제점을 식별하고, 해당 문제에 적합한 패턴을 찾아 적용하는 것이 중요하다.
또한, 코드를 특정한 패턴에 맞추려고 강제하지 않아야 한다. 디자인 패턴은 문제를 해결하는 방법이지, 코드를 작성하는 방법은 아니기 때문이다. 디자인 패턴을 남용하게 되면, 이는 과도한 엔지니어링으로 이어져 코드를 필요한 것보다 더 복잡하게 만들 수 있다. 프로그래밍에 있어서 디자인 패턴만큼 중요한 것이 KISS 원칙(Keep it simple, stupid) 이다.
참고 : Do You Recognise the 4 Early Warning Signs of Design Pattern Abuse?
참고사이트 >>>
https://sourcemaking.com/design_patterns
https://www.tutorialspoint.com/design_pattern/design_pattern_overview.htm
https://www.geeksforgeeks.org/software-design-patterns/
<디자인 패턴에 대한 블로그 정리글>
https://shoark7.github.io/programming/knowledge/what-is-design-pattern
https://medium.com/educative/the-7-most-important-software-design-patterns-d60e546afb0e
<디자인 패턴을 사용하는 이유>
https://www.developer.com/design/article.php/1474561/What-Are-Design-Patterns-and-Do-I-Need-Them.htm
https://www.codeproject.com/Tips/808058/Reasons-for-using-design-patterns
https://www.oreilly.com/content/5-reasons-to-finally-learn-design-patterns/
<디자인 패턴 사용시 주의할 점>
<디자인 패턴의 종류 정리>
https://gmlwjd9405.github.io/2018/07/06/design-pattern.html
'ComputerScience > [디자인 패턴]' 카테고리의 다른 글
[MVP] 안드로이드에 mvp 패턴 적용하기(2) - Contract 작성 (0) | 2020.03.10 |
---|---|
[MVP] 안드로이드에 mvp 패턴 적용하기(1) - mvp 패턴이란? (0) | 2020.03.10 |
디자인 패턴, MVC 패턴, MVP 패턴 요약 정리 (0) | 2020.03.04 |
MVP 패턴과 안드로이드 (0) | 2020.03.02 |
MVC 디자인 패턴 (0) | 2020.03.02 |