헤드퍼스트 디자인 패턴 개정판이 출판되었다. 안 살 이유는 없지.
바로 사서 다시 처음부터 읽어보고 있는데, 이번에는 블로그에 정리를 좀 해볼까 한다.
확장(extends) 과 구성(composition)
상속이라는 말을 좋아하지 않아서 확장이라고 했다.
추상화된 객체를 조금 더 구체적인 객체로 확장해 나가는 것이 확장이다.
예를 들어 '마법사' 객체를 확장해서 '불 마법사', '물 마법사' 등의 객체를 만들 수 있고,
'불 마법사' 객체를 확장해서 '공격형 불 마법사', '방어형 불 마법사' 등의 객체를 만들 수 있다.
'마법사'보다는 '불 마법사'가 더 구체적이고, '불 마법사'보다는 '공격형 불 마법사'가 더 구체적이다.
구성은 의존관계를 맺는 것이라고 생각하면 된다.
예를 들어 '자동차'라는 객체가 있으면
이 자동차를 구성하기 위해서는 '바퀴', '엔진' 등이 필요한데.
'바퀴', '엔진'이 바뀌면 다른 '자동차'가 된다.
즉 '자동차'는 '바퀴', '엔진'에 의존하고 있다.
Strategy Pattern
전략 패턴? 스타크래프트가 생각나는 이름이다.
전략과 전술, 전쟁광들이 좋아할만한 단어인데 난 평화주의자라서 그런지 썩 마음에 들지는 않는다.
'알고리즘 캡슐화 패턴'이라고 이름지었으면 어땠을까.
전략 패턴은 다양한 패턴의 행동을 캡슐화 해서 필요한 행동을 구성을 통해 가져다 쓰는 패턴이다.
책의 예를 빌리면 오리는 날 수 있고, 꽥꽥 울 수 있다.
난다는 행동과 운다는 행동은 오리마다 다양할 것이다.
날개로 난다, 로켓으로 난다 등의 다양한 패턴의 난다는 행동을 하나로 묶어서 패키지화하고
인터페이스를 통해 사용할 수 있게 캡슐화하여 하나의 알고리즘 군처럼 만드는 것이 전략 패턴의 핵심이다.
이렇게 캡슐화된 난다는 행동은 사용하는 쪽에서 객체를 생성할 때
의존성 주입을 통해 사용할 수도 있고, 세터를 통해 행동을 변경할 수도 있다.
한번 정해진 행동이 바뀌어서는 안 될 불변의 경우는 생성자 주입을 사용하고,
변경해야 할 필요성이 있을 때는 세터를 정의해 주면 된다.
Strategy Pattern Class Diagram
책의 예제를 그대로 코딩하는 것은 저작권 문제도 있을 것이고,
생각 없는 개발자로 생각될 수 있기 때문에 머리를 굴려
Go, Java, Kotlin, Typescript 로 구현해 보았다.
요즘 Go 만 쓰다 보니 자꾸 다른 언어들이 기억에서 멀어져서
간단히 손 푼다는 생각으로 그나마 아는 거 다 해보았다.
클래스 다이어그램은 자바 기준으로 그렸다.
전략 패턴의 핵심이 되는 수수료 알고리즘 군은 Fee 인터페이스와 Fee 인터페이스를 구현하고 있는 두 클래스이고,
Fee 인터페이스의 calculate 메서드를 통해 수수료를 계산할 수 있다.
수수료 알고리즘 군을 사용하는 곳은 송금 서비스이다.
송금 서비스인 Remit 은 추상 클래스로
calculateFee 메서드는 생성자 주입받은 Fee 구현체의 calculate 메서드를 통해 수수료를 구하고,
calculateAmount 메서드는 위에서 구한 수수료와 송금액을 합해 총송금액을 구하고 있다.
Remit 추상 클래스를 확장한 두 클래스는 Fee 인터페이스 구현체 중 필요한 것을 생성자 주입받아 사용하며,
수수료 계산은 Remit 추상클래스를 통해 구한다.
Go, Java, Kotlin, Typescript 로 구현한 소스는 git subtree 를 사용한 다음 리포지토리에서 볼 수 있다.
https://github.com/Jongwon-Hyun/design_pattern
'Programming > OOP' 카테고리의 다른 글
[Design Pattern] Factory Method Pattern, 팩토리 메서드 패턴 (0) | 2022.04.25 |
---|---|
[Design Pattern] Decorator Pattern, 데코레이터 패턴 (0) | 2022.04.21 |
[Design Pattern] Observer Pattern, 옵저버 패턴 (0) | 2022.04.19 |
SOLID 원칙 (0) | 2017.08.17 |
OOP(Object Oriented Programming) 기본 개념 (0) | 2017.08.04 |
댓글