디자인 패턴
프레임워크
일관성 있는 코드
💡 3의 규칙 (패턴의 조건)
최소 세가지의 서로 다른 시스템에 특별한 문제없이 적용할 수 있고, 유용한 경우에만 패턴으로 간주할 수 있다.
→ 경험을 통해서 축적한 실무 지식을 요약하고 전달하는 것이 패턴이다. 따라서 실무에 사용할 수 있어야 한다.
패턴은 홀로 존재하지 않는다.
패턴을 분류하는 가장 일반적인 방법 (패턴 범위나 적용 단계)
아키텍처 패턴
디자인 패턴
이디엄
→ 아키텍처 패턴, 디자인 패턴, 이디엄은 기술적인 문제를 해결하는 데 초점을 맞추고 있다.
→ 도메인 내의 개념적인 문제를 해결하는 데 초점을 맞추고 있다.
기술적인 문제 해결 | 도메인 내의 개념적인 문제 해결 |
---|---|
아키텍처 패턴, 디자인 패턴, 이디엄 | 분석 패턴 |
객체지향의 목표는 객체가 올바른 책임을 갖고 다른 객체들과 유연한 협력 관계를 구축하는 일이다.
대부분 훌륭한 품질의 설계를 얻기 위해서 많은 시간을 들여야 한다.
패턴
strategy: 알고리즘을 동적으로 교체할 수 있는 역할과 책임의 집합을 제공한다.
bridge: 역할과 책임을 추상화와 구현 두 개의 집합으로 분배한다
observer: 유연한 통지 매커니즘을 구축하기 위해서 객체 간 결합도를 낮출 수 있는 역할과 책임의 집합을 제공한다
💡 디자인 패턴의 목적
특정한 변경을 캡슐화함으로써 유연하고 일관성 있는 설계를 할 수 있게 경험을 공유한다.
구조가 중요하기 보단 어떤 점을 캡슐화할 수 있는지 이해하는게 중요하다.
패턴은 출발점이지 도착점이 아니다.
목적에 맞게 변경해야지, 있는 그대로 구조를 관철하는 것은 오히려 유연하지 못하다.
패턴이 적용된 최종 결과보단 패턴을 적용하여 리팩토링하는 이유를 이해하는 게 더 도움된다.
패턴은 경험일 뿐 소프트웨어에 녹이는 건 개발자고, 각 애플리케이션의 상황도 제각각이기 때문이다.
디자인 패턴은 언어에 종속적이지 않다. 따라서 설계 아이디어를 프로그래밍 언어 특성에 맞춰 가공해야 하고 매번 구현 코드를 재작성해야 한다는 단점이 있다.
재사용 관점에서 설계 재사용보다 더 좋은 방법은 코드 재사용이다.
가장 이상적인 형태의 재사용 방법은 설계 재사용과 코드 재사용을 적절한 수준으로 조합하는 것이다. 컴포넌트는 코드 재사용만을 강조한다. 설계 재사용을 강조한 디자인 패턴은 재사용을 위해서 매번 유사한 코드를 작성해야 한다.
💡 설계를 재사용하면서도 유사한 코드를 반복적으로 구현하는 문제를 피할 수 있는 방법은 없을까?
이에 대한 답이 프레임워크다.
→ 이러한 정의는 설계 재사용과 코드 재사용을 모두 만족한다.
상위 모듈이 하위 모듈보다 비교적 많이 재사용된다.
상위 모듈이 하위 모듈에 의존하면 하위 모듈이 변경될 때 상위 모듈도 함께 변경되어야 한다.
구조적으로 불안정하다.
하위 모듈이 상위 모듈을 의존해야 재사용이 용이하다.
그러므로 의존성 역전 원칙 관점에서 추상화에 상위/하위 모듈 모두 의존하게 만들어야 한다.
💡 추상화는 어떻게 할까?
변하는 것과 변하지 않는 것을 분리하라.
→ 프레임워크는 재사용 가능해야 하므로 배포 단위로 분리한다.
패지키 분리는 변하지 않는 것과 변하는 것을 별개의 패키지에 분리해야 한다.
→ 구현체는 상위 추상화 패키지와 분리된다.
즉, 추상화와 이에 대한 구현이 분리된다. (컨텍스트 독립성)
이를 통해 일관성 있는 협력을 지닌 프레임워크를 사용할 수 있다.
객체 지향 설계에서 재사용성은 객체들의 협력 흐름과 같다.
→ DIP에서 협력 흐름을 잘 짜도록 도와준다.
변경이 자주 되는 프로그램에 DIP가 없다면 유연한 프로그램을 만들 수 없다. 절차지향적인 설계가 되기 때문이다.
DIP를 사용한 프레임워크 사용 시 주체가 애플리케이션에서 프레임워크로 이동한다.
의존성 역전 시 제어 흐름의 주체도 변경되며, 이를 제어 역전 원칙, 할리우드 원칙이라고 한다.
프레임워크는 일반적인 해결법을 정의하고, 애플리케이션은 이에 따라 변경될 수 있는 동작을 구현한다.
💡 훅 (hook)
프레임워크에서 의도적으로 비워둔 부분은 훅(hook)이라고 한다. 프레임워크의 코드 안에서 실행되는 부분이다.
프레임워크를 처음 쓰면 제어 주도권이 남에게 넘어가기 때문에 불안할 수 있다. 그러나 이 모든게 제어의 역전과 동시에 코드 재사용을 가능하게 해줌을 이해하면 좋다.
이 책을 읽은 지 한 달 쯤 되었을 때는 책 선택을 후회하기도 했다. 어려운 내용과 반복되는 구성으로 인해 지금 학습하기에는 지나치게 어려운 것을 시도했던 것은 아닐까 하는 생각이 들었다.
그에 반해 독서 모임을 함께 했던 구성원들은 매 주차마다 무언가 얻어가는 게 있는 것처럼 보여서 위축되기도 했다.
그러나 책을 끝까지 읽으면서 생각이 조금 달라졌다.
SOLID를 코드로 이해하고, 우테코 과제에 조금씩 적용해보면서 내 코드도 조금씩 객체지향적으로 변해가는 것이 느껴졌다. DIP와 OCP를 준수하는 코드를 짜기 위해 노력했고, 캡슐화가 단순히 데이터의 포장뿐만 아니라 조금 더 범용적인 개념임을 느꼈다.
개발자는 항상 변화하는 요구사항에 맞춰 내일 바로 수정할 수 있는 코드를 작성해야 한다. 그런 의미에서 이전까지는 좋은 개발자가 아니었다면, 이 책을 읽은 뒤로는 좋은 개발자에 가까워진 것 같다.
물론 객체지향은 여전히 어렵다.