Head First Design Pattern 요약 #1 - Strategy, Observer


Chapter 1. 디자인 패턴 소개

최초설계

Duck[꽥(), 수영(), 표시()] <--- 오리1 [표시()]
                           <--- 오리2 [표시()]

날기 추가 : 오리1, 오리2도 날수 있게 됨

Duck[꽥(), 수영(), 표시(), 날기()] <--- 오리1 [표시()]
                                   <--- 오리2 [표시()]

고무로된 오리도 날수 있게됨 : 문제발생

Duck[꽥(), 수영(), 표시(), 날기()] <--- 오리1 [표시()]
                                   <--- 오리2 [표시()]
                                   <--- 고무오리 [꽥(//삑삑으로 오버라이드), 표시()]

고무로된 오리도 날수 있게됨 : 고무오리의 날기()를 오버라이드로 처리하여 못날게 함

Duck[꽥(), 수영(), 표시(), 날기()] <--- 오리1 [표시()]
                                   <--- 오리2 [표시()]
                                   <--- 고무오리 [꽥(//삑삑으로 오버라이드), 표시(), 날기(//아무것도 안함)]

나무오리 : 꽥을 아무것도 안함으로 오버라이드

Duck[꽥(), 수영(), 표시(), 날기()] <--- 오리1 [표시()]
                                   <--- 오리2 [표시()]
                                   <--- 고무오리 [꽥(//삑삑으로 오버라이드), 표시(), 날기(//아무것도 안함)]
                                   <--- 나무오리 [꽥(//아무것도 안함), 표시(), 날기(//아무것도 안함)]

매번 오버라이드로 뻘짓하기 싫어져서 인터페이스를 사용하기로 함

날수있음[날기()]                                     <--- 오리1 [표시(), 날기(), 꽥()]
꽥꽥거릴수 있음[꽥()]                                <--- 오리2 [표시(), 날기(), 꽥()]
오리[수영(), 표시(), 기타오리관련메소드()]           <--- 고무오리 [표시(), 꽥()]
                                                     <--- 나무오리 [표시()]

변화

날기()를 고쳐라 요구사항 들어옴 -> '날수있음'을 상속받은 모든 오리를 고쳐야 -> 오류발생 높아질 수도 있다.

디자인 원칙 #1

Application에서
달라지는 부분과
달라지지 않는 부분을 (요놈을 뽑아서(리팩토링) 캡슐화하면 요 부분만 고치거나 확장가능하다.)
분리해라

바뀌는 부분과 안 바뀌는 부분 분리

바뀌는 부분    : 날기(), 꽥() --> {꽥(), 삑(), 뽕()} 처럼 관련된 클래스 집합을 만듬
안 바뀌는 부분 : 표시() 

디자인 원칙 #2

구현이 아닌 인터페이스에 맞춰 프로그래밍 한다.

위의 각 클래스 집합을 인터페이스로 만들어봄

날기행동_인터페이스[날기()]    <--- 날개로날기[날기()]
                               <--- 못날기[날기(//아무것도 안함)]

다형성을 위해 추상수퍼클래스로도 사용 가능

동물_추상[소리냄()]    <--- 강아지[소리냄(){멍()}&nbsp; 멍(){짖음}]
                       <--- 고양이[소리냄(){뮤()}&nbsp; 뮤(){울음}]
개 만들기 #1                    개 만들기 #2                          개 만들기 #3
Dog d = new Dog();              Animal animal = new Dog();            a = getAnimal();
d.멍();                         animal.소리냄();                      a.소리냄();
실제 구현
....

"A는 B이다" 보다 "A에는 B가 있다"

구성을 사용함으로써 유연성을 크게 향상 시킬 수 있음

디자인 원칙 #3

상속보다는 구성(composition)을 사용하라

드디어 첫번째 패턴

스트래티지 패턴(strategy pattern)
알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만듬
스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.

디자인 패턴 필요성

  1. 개발자간 서로 사용하는 패턴 용어
  2. 패턴을 이용하면 간단한 단어로 많은 것을 얘기할 수 있음 : 이번건은 스트래티지 패턴으로 할꺼야
  3. 디자인에 더 집중할 수 있음 : 구현 생각하느라 논점이 빗나가지 않음
  4. 전문용어 사용으로 개발팀의 능력 향상 : 오해의 소지가 줄고 빠른 작업 가능
  5. 신참개발자에게 자극

참고자료 : 다형성(polymorphism)

 

참고자료 : 일반클래스, 추상클래스, 인터페이스

 

쉬어가기
내가 진정 중요하게 생각하는 것들 : 김창준 (애자일 컨설팅 대표)
http://www.ibm.com/developerworks/kr/library/dwclm/20080226/
테러리스트에서 버그까지 : 김창준 (애자일 컨설팅 대표)
http://www.ibm.com/developerworks/kr/library/dwclm/20080422/

 

Chapter 2. 옵져버 패턴

기상 모니터링 Application 개발 의뢰

온도/습도/압력센서 --- 기상스테이션 <--- WetherData객체 ---> 디스플레이 장비(현재상태, 통계, 예보)
                                                             확장가능하도록 API 도 만들것

WetherData 클래스

WetherData[getTemperature(), getHumidity(), getPressure(), mesurementsChange()]
↖ 온도getter ↖습도getter   ↖기압getter   ↖기상관측값이 갱신될때마다 알려주는 메소드

첫번째 대충 만든 코드

public class WeatherData {
    // 인스턴스 변수 선언...
 
    public void measurementsChanged() {
        float temp = getTemperature();
        float humidity = getHumidity();
        float pressure = getPressure();
 
        currentConditionsDisplay.update(temp, humidity, pressure);
        statisticsDisplay.update(temp, humidity, pressure);
        forecastDisplay.update(temp, humidity, pressure);
    }
 
    // 기타 메소드...
}

위 코드의 문제점은?

  • parameter 가 맨날 똑같다.. 공통 부분
  • 9~11줄은 바뀔 수 있는 부분 -> 캡슐화 하자 (스트래티지 패턴)
  • 9~11줄은 구체적인 구현이므로 다른 디스플레이를 위해서는 코드를 고치는 수밖에 없다.

옵져버 패턴이란?

  • 옵져버 패턴 = 출판사(subject) + 구독자(observer)
  • 구독 / 해지 가능
  • subject 객체는 데이타가 달라지면 observer 객체에게 값을 전달

  

Observer Pattern

한 객체의 상태가 바뀌면
그 객체에 의존하는 다른 객체들에게 연락이 가고 자동으로 내용이 갱신되는
ont-to-many 의존성을 정의함

옵저버 패턴 : 클래스 다이어그램

느슨한 결합

느슨한 결합(Loose Coupling) : subject와 observer가 느슨하게 묶임 (서로가 서로를 모름)

  • subject가 observer에 대해 아는건 observer가 특정 인터페이스를 구현한다는 것 뿐 : update()
  • observer는 언제든 새로 추가 가능
  • 새 observer를 추가해도 subject를 변경할 필요 없음
  • subject 와 observer는 독립적으로 재사용 가능
  • subject 또는 observer가 변경되어도 서로 영향 안 미침

 

디자인 원칙 #4
서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용하라
--> 변경사항이 생겨도, 객체사이의 상호 의존성을 최소화하여 변경가능한 유연성 확보 가능
사용자 삽입 이미지

기상 스테이션 설계

...

Java에서는...

java.util.Observer 인터페이스, java.util.Observeable 클래스 가 있음
스윙에서도 옵저버 패턴을 사용함 (e.g. JButton 의 ActionListener)

참고자료
닷넷환경 UML : http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39134439,00.htm
StarUML : http://cafe.naver.com/staruml
샤프심 흑심 품다 : http://blog.empas.com/mcm27xx/read.html?a=4093369
UML 이해하기 : Download

광고

댓글 남기기