디자인 패턴 1. 소개

2020. 2. 8. 17:50Programming/Design Pattern

디자인 패턴이 뭔가요?

Design Pattern이란 말만 들었을 때에는, 뭔가 그림을 그려야 할 것 같지만 사실 디자인은 단순히 그림을 그리는 의미가 아니라 '설계'의 의미를 가지고 있습니다. 즉, 디자인은 설계에 해당합니다. 그렇다면 프로그래밍에서 디자인 패턴은 어떤 의미일까요? '프로그램 설계 유형' 정도로 풀어서 쓸 수 있지 않을까요?

프로그램을 설계한다는 의미는 단순히 코딩을 하는 것 그 이상의 문제를 이야기합니다. 진부하지만 회원가입의 예를 들어보고자 합니다. 회원가입에는 보통 성별을 남/녀로 받습니다. 그렇다면 회원 정보를 담을 클래스를 만들 때, 어떻게 해야할까요? 일단 첫 번째 예를 봅시다.

ManMember와 WomanMember를 각각 Class로 만들었습니다. 이름과 나이를 각각 멤버 변수로 가지네요. 괜찮나요? 프로그래밍을 배운지 얼마 되지 않은 사람도 뭔가 잘못되었단 걸 알 수 있습니다.

  • 남성회원/여성회원을 나누긴 했지만, 가지고 있는 멤버는 전부 동일합니다. 불필요한 코드 중복으로 볼 수 있습니다.
  • 만일 회원가입을 받을 때 주소도 같이 받게 하고 싶으면, 남성회원과 여성회원에 전부 '주소'라는 멤버를 추가해야합니다.

그렇다면 코드의 중복을 없애기 위해 아래와 같이 바꿔보는 건 어떨까요?

두 Class를 Member라는 하나의 Class로 합추고, 성별을 Enum으로 정의해서 멤버에 포함시켰습니다. 이렇게 불필요한 코드 중복은 줄었습니다. 앞으로 회원 클래스에 새로운 멤버가 추가되어야 하더라도 걱정이 없습니다. '코드의 중복, 스펙 변경에 대한 대처 용이함'이라는 문제를 해결한 것입니다. '회원 정보가 있어야 하며, 이는 남/녀 두 성별로 구분할 수 있다'는 발상의 시작점은 똑같았으나, 이를 어떻게 구현하느냐에 대해서는 다른 결과가 나왔습니다. 설계가 다른 것입니다. "스펙 변경"이라는 관점에서 전자의 설계는 대처가 힘든 설계고, 후자의 설계는 비교적 대처하기 쉬운 설계입니다. 비교 대상이 이 둘뿐만이므로 간단해 보이지만, 스펙 변경의 폭이 넓어질 수록 이 설계의 선택은 더 중요하게 다가옵니다.

알고보니 이 회원 정보는 교육부에서 사용하는 것이었습니다. 회원은 '학생', '교사'로 나뉘어야 합니다. 학생은 '담임선생'을 하나씩 가져야합니다. 이 때, 단순히 Member class에 학생/교사 구분용 멤버와 '담임선생' 멤버를 넣어버리면, 올바른 설계일까요? 프로그래머의 실수로 '담임이 있는 교사'가 생겨날 수도 있습니다. 이 경우에는 오히려 Member Class를 부모 클래스로 두고, Student Class, Teacher Class라는 자식 클래스를 만드는 게 나을 수도 있습니다.

이렇듯 설계는 코딩보다 상위 레이어의 단계의 개념입니다. 적절한 설계를 잘 할 수록 프로그램의 변경에 잘 대처할 수 있습니다. 그리고 이러한 설계 방법의 족보가 바로 디자인 패턴입니다.

디자인 패턴은 성현의 지혜(?)입니다.

대장간의 풀무질이나 방직 기술보다는 한참 그 역사가 얕지만, 프로그래밍도 나름 유서가 깊은 기술 분야입니다. 그렇기 때문에, 일찌기 수없이 많은 사람들이 프로그래밍을 하면서 비슷한 문제들에 직면했고, 각자의 해결방법을 종합해 유형으로 정리했습니다.

인류가 처음부터 수영을 할 줄 알았던 것은 아닙니다. 그러나 시간이 지나면서 정석적인 수영법들이 정립되었습니다.

프로그래밍의 해결법을 유형화했다는 것이 잘 와닿지 않는다면, 수영법을 생각해보면 될 것 같습니다. 분명히 최초의 인류들은 수영을 잘 하지 못했을 것입니다. 그러나 시간이 흐르면서 누군가가 '어? 이 수영법 진짜 괜찮네!' 하면서 새로운 영법을 발견하고, 이를 전파했겠죠. 이제 수영 대회에서 개헤엄을 치는 선수는 없습니다. 이미 알려진 수영법이 가장 검증된 수영법이란 것을 잘 아니까요.

디자인 패턴은 개발자들의 수영법입니다. 어떠한 문제 상황에 직면했으며, 그것을 어떻게 해결해보고자 했고, 그 결과 어떤 방법이 효과가 있었는지에 대한 결과물의 집합체입니다. 라이브러리가 어떤 의미로 코드의 재사용이라면, 디자인 패턴은 경험의 재사용이라 할 수 있습니다.

변하지 않는 유일한 것은, "코드는 끊임없이 변한다"는 점입니다.

한 번 만들고 나서 두번 다시 유지 보수하지 않을 코드라면, 디자인 패턴은 필요가 없습니다. 그러나 대부분의 경우는 스펙 변경을 통해 기능을 추가하거나, 원래 있던 부분을 고치기도 합니다. 디자인 패턴을 만든 사람들이 당면했던 문제는, 이미 만들어 놓은 프로그램을 수정해야하는 상황이 왔을 때 생겼던 문제들입니다. 즉, 디자인 패턴은 본질적으로 "앞으로 이 프로그램이 변할 수 있으며, 그 가능성을 염두했을 때, 현재 어떻게 설계해야만 하나"에 관한 고찰입니다.

디자인 패턴은 개발자간 소통을 원활하게 합니다.

"나는 얼굴과 배를 물 밖으로 내놓은 상태로 팔을 뒤로 휘둘러서 가는 수영밖에 못 해"와 "나는 배영밖에 못 해"의 차이는 무엇일까요? 본질적으로 의미는 같으나, 전자는 뭔가 다 듣고나면 김이 빠집니다. '그거 배영이잖아. 배영이라고 말해주면 안 돼?' 라는 말이 절로 나오죠. 같은 대상을 너무 많은 단어로 설명함으로써 말하는 사람이나 듣는 사람이나 양 쪽 다 피곤해졌습니다. 결국 전달된 정보는 똑같단 점에서 손해도 이런 손해가 아닐 수 없습니다.

일상 회화라면 이 정도는 애교로 넘어갈 수 있습니다만, 회사에서 다른 사람들과의 업무가 이런 식으로 진행된다면 난감할 수 있습니다. "파이널 클래스에 프라이빗 생성자를 걸어서 외부로부터의 객체 생성 자체는 막되, 겟 인스턴스라 불리는 스태틱 퍼블릭 메소드를 하나 빼고, 인스턴스가 없을 때에는 새로 생성해서 주되, 이미 있다면 그것을 그대로 주는 방식으로 구현을 했으므로 객체 중복 생성을 막으면서, 여러 클래스에서 동일한 녀석을 참조할 수 있도록 했습니다" 라는 설명은 "이 클래스는 싱글톤으로 작동합니다" 라는 한 문장으로 정리가 됩니다. 합의된 용어만 있다면 설명충이 되지 않아도 의미 전달을 정확하게 할 수 있게 됩니다. 디자인 패턴은 이러한 소통에서도 유용하게 사용될 수 있습니다. 

마치며

이상으로 디자인 패턴의 개념, 필요성에 대해서 간단히 작성해보았습니다. 혹시라도 제가 잘못 알고 있는 부분이 있더라면 얼마든지 피드백해주셨으면 합니다. 다들 좋은 하루 되세요.