DesignPatternSmalltalkCompanion:2.2

From 흡혈양파의 번역工房
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

2.2 장면 2: 원칙은 깨어져선 안 된다.

[며칠 후, 돈은 까다로운 설계 문제로 인해 제인에게 도움을 요청한다.]

돈: 제인, 시간 있어?
제인: 물론. 무슨 일이야?
돈: 또 다른 설계 문제가 생겨서 말이야, 너한테 도움을 받을 수 있을까 해서.
제인: 물론이지.
돈: 심사 과정이 어떻게 작동할지에 대해 몇 가지 측면을 알아보려고 해. Claim이 어떻게 수락되어 지급되는지와 어떻게 거부되는지에 대해서 말이야.
제인: 응, 지난번에 네가 설명해줬던 기억이 나.
돈: 내 문제는 바로 이거야. 보상금을 청구하는 방법으로 이렇게 내려오거든. 요구문서에서 설명하는 원칙들이 서로 달라서 말이야. 어떻게 나타낼지 모르겠어.
제인: 요구문서 좀 보여줄래? [돈이 문서를 건네주고 다음 단락을 함께 읽는다]
  • 정책은 보장되는 항목의 목록으로 구성되어 있고, 각 항목과 관련된 지급원칙도 함께 있 다. 지급에는 몇 가지 원칙이 있다:
  • 특정 항목에서는 절차와 관련해 전혀 보상하지 않는다 (예: 보상 거부).
  • 특정 항목에서는 균일한 달러 금액을 지급한다 (예: 123.4 절차의 경우 $25를 지불한다).
  • 특정 항목에서는 해당하는 비용 중 일정 비율만 지급한다 (예: 234.5 절차의 경우 병원비의 50%를 지급한다).

그리고 지급원칙이 두 가지가 더 있어.

  • 손절매 원칙(Stop-loss rule)은 개별 항목에 지급되는 최대금액을 조절한다 (예: 비용의 70% 또는 $500 중 적은 금액을 지급한다).
  • 쿼리기반의 원칙(Query-based rule)은 청구인의 속성을 기반으로 한다 (예: 청구인이 여성일 경우 본 절차에 $200를 지급하고; 그 외에는 $150를 지급한다).
돈: 어떻게든 이런 절차 코드를 서로 다른 원칙에 맞출 수는 있었어. 하지만 각 원칙은 사용자가 결정한단 말이지! 원칙을 Policy로 코드화할 수 있으면 좋겠지만, 문제는 사용자가 어떤 원칙을 원할 것인지 미리 아는 방법이 없다는 거야.
제인: 내가 보기엔 각각의 "원칙"들이 보상 전략(Strategy)으로 들리는데?
돈: 그렇게 말하니 흥미로운데? 무슨 의미지?
제인: Strategy는 또 다른 패턴이야. Strategy 패턴의 의도를 읽어줄게 [디자인 패턴 서적에 다가가 책을 펼친 후 다음 문장을 읽는다] : "알고리즘 군을 정의하고, 각각의 알고리즘을 별도의 클래스로 캡슐화하여 상호 교환이 가능하게 만든다. Strategy 패턴은 이를 사용하는 클라이언트에게 영향을 주지 않고 독립적으로 다양하게 나타난다."
돈: 글쎄, 보상은 알고리즘이 아닌 것 같은데. 그래도 시도는 해보고 싶어. Strategy 패턴이 어떻게 실행되는지 보여줘 봐.
제인: 각각의 원칙을 하나의 Strategy 객체로 만들 순 없는지 살펴보자. 기본적으로 각 원칙은 한 라인 항목에 대한 총합을 계산하는 것이 맞지?
돈: 맞아.
제인: 그러니까 각각의 객체는 reimbursementFor: aLineItem라고 불리는 메시지를 이해해야만 해. 각 원칙마다 하나의 클래스가 있어. 네가 설명한 첫 번째 원칙이 뭐였지?
돈: "절차와 관련해 전혀 보상하지 않는다."
제인: 특별한 사례의 경우네. 이 원칙을 reimbursementFor: 로 구현하는 건 쉽겠어: 반환(return) 값이 항상 0이 되니까.
돈: 두 번째는 어때? 균일한 달러 금액을 지급하는 원칙 말이야.
제인: 보상금액을 계속 유지하는 인스턴스 변수가 하나 있을 거야. 그럼 reimbursementFor: 메소드가 그 인스턴스 변수 값을 반환할거야.
돈: 이제 이해가 가기 시작했어. 그럼 "라인 항목에 해당하는 비용 중 일정 비율만 지급"하는 원칙은 퍼센트를 저장하고 reimbursementFor: 메소드가 라인 항목의 비용에 퍼센트를 곱한 결과를 반환하겠지?
제인: 맞아. 3개의 클래스 계층구조는 이렇게 되겠지.

Dpsc 2.2 01.png

제인: Claim은 특정 절차 코드에 어떤 원칙을 적용할 것인지 찾아본 후에 그 절차에 맞는 원칙을 적용할 필요가 있어.
돈: 나쁘지 않은 걸! 문제 일부는 해결됐네. 그럼 다음 건 어때? 손절매 원칙은 앞서 말한 두 원칙처럼 작동하질 않아. 다른 원칙 하나를 먼저 실행한 후에 그 결과를 바탕으로 상환금액을 결정해야 할 것 같은데.
제인: 네가 뭔가 중요한 걸 발견한 것 같은데. 한번 찾아볼게 [디자인 패턴 서적을 들고 책을 넘기기 시작한다]. 여기 새로운 행위를 추가하기 위해 런타임에서 객체의 행위를 변경하는 방법을 알려주는 패턴이 있어. 아, 찾았다! Decorator 패턴이야 [책을 넘겨 177페이지에 실린 다이어그램을 돈에게 보여준다]. 이 다이어그램에서 어떻게 Decorator가 기존 객체가 아닌 다른 객체의 인스턴스를 포함시키면서 기존 객체와 동일한 인터페이스를 구현하는지 이해하겠어? 네 문제도 비슷하게 해결하면 될 것 같아.
돈: 또 헷갈리네. 기존 객체는 뭐고 다른 객체는 뭐야?
제인: 구체적으로 말해줄게. StopLossStrategy라 불리는 다른 원칙이 있다고 가정하고, 그 안에 다른 Strategy가 포함되어 있다고 쳐. 그럼 이 원칙은 원칙에 포함된 Strategy 로 메시지를 전송(forwarding)한 다음 그 결과가 손절매 금액을 초과하는지 확인함으로써 reimbursementFor: 메소드를 구현하는 거야.
돈: '[망설이며] 네가 무슨 말을 하는지 알 것 같아. 이런 모양이 되겠다는 말이지? [제인의 그림을 가져와 새로운 클래스를 추가한다].

Dpsc 2.2 02.png

제인: 맞아.
돈: 그럼 이 디자인 패턴이란 건 정말 효과적인걸! 하나의 설계에 하나 이상의 패턴을 통합했잖아. 앞에서 네가 설명한 방법대로라면 독자적으로 작동할 줄 알았거든.
제인: 항상 그런건 아냐. 디자인 패턴은 하나만 사용할 수 있지만 대개는 하나의 설계에 몇 가지 패턴이 함께 사용되는 걸 볼 수 있을 거야. 함께 자주 사용되는 특정한 패턴들이 있어. [디자인 패턴]의 각 패턴 마지막 부분에 "관련 패턴"이라는 절에서 열거하고 있어.
돈: 저자들이 그걸 생각해 냈다니 다행이야. 하지만 어떤 패턴을 적용할 것인지는 어떻게 알지? 넌 그냥 임의로 뽑은 것 같아서 말이야.
제인: 꼭 그렇지만도 않아. 내가 패턴을 선택하는 과정이 전혀 과학적이지 않다는 건 인정하지만 말이야. 지난 번 PLoP(Patterns Languages of Programs) 학회에서 누군가 한 패턴 전문가에게 어떻게 패턴을 결정했는지 질문하는 걸 우연히 들었거든. 전문가는 "내가 읽었지만 절반은 잊어버린 종이 조각에 대해 생각해보고, [디자인 패턴] 내부의 맨 앞 양면 페이지를 살피기도 하고, 때로는 추측에 맡겼죠,"라는 말을 했어. 패턴을 읽고 제2의 천성이 될 때까지 충분히 적용해보는 것이 핵심인 것 같아.
돈: 그렇구나. 패턴에 관해 실제로 읽을 필요가 있는 것 같아.
제인: 정말 많이 배울 수 있을 거야. 내 책을 빌려갈래? [책을 돈에게 건네준다].
돈: 당연하지. [그는 책을 받는다]. 가서 이 설계를 문서화 시켜야겠어. 그건 그렇고 쿼리기반의 원칙에 대해서는 해줄 말 있어?
제인: 글쎄, 런타임 쿼리를 처리하는 Interpreter 패턴을 이용할 수 있지. [디자인 패턴] 243페이지를 찾아 봐.
돈: 좋았어! 한 번 읽어볼게. [제인의 칸막이 사무실을 급히 뛰어나가며 책을 흔든다]