Presentation is loading. Please wait.

Presentation is loading. Please wait.

Java로 배우는 디자인패턴 입문 Chapter 17. Observer 패턴 상태의 변화를 통지한다

Similar presentations


Presentation on theme: "Java로 배우는 디자인패턴 입문 Chapter 17. Observer 패턴 상태의 변화를 통지한다"— Presentation transcript:

1 Java로 배우는 디자인패턴 입문 Chapter 17. Observer 패턴 상태의 변화를 통지한다
2004-1 덕성여자대학교 컴퓨터학부

2 observer 01. Observer 패턴 관찰자 관찰 대상의 상태가 변하면, 관찰자에게 통지된다.
객체의 상태 변화에 따른 처리를 기술할 때 유용하게 사용된다. /42

3 수를 많이 생성하는 객체를 관찰자가 관찰해서, 그 값을 표시하는 프로그램 관찰자의 종류에 따라 표시 방법이 다르다
02. 예제 프로그램 수를 많이 생성하는 객체를 관찰자가 관찰해서, 그 값을 표시하는 프로그램 관찰자의 종류에 따라 표시 방법이 다르다 DigitObserver: 값을 숫자로 표시함 GraphObserver: 값을 간이 그래프로 표시함 /42

4 02. 예제 프로그램 /42

5 02. 예제 프로그램 클래스 다이어그램 관찰자 관찰대상 /42

6 Observer 인터페이스 02. 예제 프로그램 관찰자를 표현하는 인터페이스 update(NumberGenerator)
/42

7 NumberGenerator 클래스 02. 예제 프로그램 수를 생성하는 클래스
execute( ), getNumber( ): 추상 메소드 observer 필드: NumberGenerator를 관찰하고 있는 Observer들을 보관하고 있는 필드 addObserver(Observer) Observer를 추가할 때 호출하는 메소드 deleteObserver(Observer) Observer를 삭제할 때 호출하는 메소드 notifyObservers( ) Observer 전원에게, “나의 내용이 갱신되었기 때문에 당신의 표시도 갱신해주세요”라고 알려주는 메소드 Observer들의 update(this) 메소드를 차례차례 호출한다. /42

8 RandomNumberGenerator 클래스
02. 예제 프로그램 RandomNumberGenerator 클래스 NumberGenerator의 하위 클래스 난수를 생성한다 java.util.Random 클래스 이용 number 필드: 생성된 난수를 저장하는 변수 getNumber( ): number 필드의 값을 반환함 execute( ): 0~49 까지의 난수 20개를 생성하고, 그 때마다 notifyObservers를 호출하여, 관찰자들에게 통지한다. Random 클래스의 nextInt( ) 이용함 /42

9 DigitObserver 클래스 02. 예제 프로그램 Observer 인터페이스를 구현한 구체적인 관찰자
관찰한 수를 ‘숫자’로 표시함 update(NumberGenerator) 인자로 전달된 NumberGenerator의 getNmber( )를 이용하여 수를 얻어서 화면에 출력한다. 출력한 후, 표시된 모습을 잘 알 수 있도록 Thread.sleep( )을 이용하여 스피드를 늦춘다. Thread.sleep(100) (100/1000 = 0.1 초) 동안 CPU를 반환하고 쉬겠다는 뜻 /42

10 GraphObserver 클래스 02. 예제 프로그램 Observer 인터페이스를 구현한 구체적인 관찰자
관찰한 수를 ‘간단한 그래프’로 표시함 관찰한 숫자만큼의 ‘*’를 출력한다 /42

11 Main 클래스 02. 예제 프로그램 RandomNumberGenerator 인스턴스 1 개 생성함 관찰자 2개 생성함
RandomNumberGenerator의 execute( )를 이용해서 수를 생성한다 난수가 발생될 때마다, 관찰자들은 각자의 방식대로 수를 ‘표시’한다. /42

12 ConcreteSubject(구체적인 관찰대상자) 역할
03. 등장 역할 Subject(관찰 대상자) 역할 ‘관찰되는 쪽’을 나타냄 Observer 역할을 등록하는 메소드와 삭제하는 메소드를 가진다. 현재의 상태를 얻어갈 때 호출하는 메소드도 제공함 예제에서는, NumberGenerator 인터페이스가 해당됨 ConcreteSubject(구체적인 관찰대상자) 역할 구체적인 ‘관찰되는 쪽’을 나타냄 상태가 변하면, 등록된 Observer 역할에게 통보함 예제에서는, RandomNumberGenerator 클래스가 해당됨 /42

13 ConcreteObserver(구체적인 관찰자) 역할
03. 등장 역할 Observer(관찰자) 역할 ‘관찰하는 쪽’을 나타냄 Subject 역할로부터 상태변화를 통보받는 역할 예제에서는, Observer 인터페이스가 해당됨 통보받을 때, 관찰자의 update( ) 메소드가 호출됨 ConcreteObserver(구체적인 관찰자) 역할 구체적인 ‘관찰하는 쪽’을 나타냄 상태 변화가 관찰 대상으로부터 통보되면(즉, update 메소드가 호출되면) 그 메소드안에서 Subject 역할의 현재 상태를 얻어서 적당한 일을 수행한다. 예제에서는, DigitObserver와 GraphObserver 클래스가 해당됨 /42

14 03. 등장 역할 /42

15 여기서도 교환 가능성이 등장한다. 04. 독자의 사고를 넓혀주는 힌트 RandomNumberGenerator 클래스는,
현재 자신을 관찰하고 있는 것이 DigitObserver의 인스턴스인지 GraphObserver의 인스턴스인지 모른다. 다만, 이들이 Observer 인터페이스를 구현하고 있다는 것만 안다. 한편, DigitObserver 클래스는, 자신이 관찰하고 있는 것이 RandomNumberGenerator의 인스턴스인지 다른 XXXXXNumberGenerator의 인스턴스인지 신경쓰지 않는다. 다만, 관찰대상이 NumberGenerator의 하위 클래스의 인스턴스이고 getNumber 메소드를 가지고 있다는 것만 알고 있다. 관찰자와 관찰 대상을 논리적으로 분리함으로써, 각각을 쉽게 교체할 수 있다 => 확장성/교환 가능성이 높아진다. /42

16 04. 독자의 사고를 넓혀주는 힌트 갱신을 위한 정보의 취급
NumberGenerator는 update 메소드를 사용해서 ‘갱신되었습니다’라고 Observer에게 통지한다. 이때, Observer 클래스의 update( )의 입력인자는 NumberGenerator 이다. Observer는 입력인자로 들어온 NumberGenerator를 이용하여 원하는 정보를 추출한다. NumberGenerator가, 관찰자가 필요한 정보만 넘겨줄 수도 있다. void update(NumberGenerator generator){ //generator.getNumber() 이용 } void update(int number){ //number 이용 } subject(관찰대상)이, 관찰자가 필요한 정보가 무엇인지 알아야 하는 부담을 가지고 있다. /42

17 ‘관찰’하는 것이 아니고, 사실은 ‘통지’를 받는다.
04. 독자의 사고를 넓혀주는 힌트 ‘관찰’하는 것이 아니고, 사실은 ‘통지’를 받는다. Observer의 역할이, 사실은 Subject로부터 통지가 오기를 기다리는, 수동적인 역할을 하고 있다. 그래서, Observer 패턴을 Publish-Subscribe 패턴이라고도 한다. /42

18 Model/View/Controller(MVC)
04. 독자의 사고를 넓혀주는 힌트 Model/View/Controller(MVC) Smalltalk 언어에서, 하나의 데이터 모델을 여러 형태로 보여 주고자 할 때 사용되는 유명한 패턴이다. Model과 View의 관계는, Observer 패턴에서 Subject와 Observer의 역할과 서로 대응된다. /42

19 java.util.Observer 인터페이스
05. 보강 JDK에서 제공되는 java.util.Observer 인터페이스와 java.util.Observable 클래스는, Observer 패턴의 일종이다. java.util.Observer 인터페이스 java.util.Observer와 java.util.Observable를 사용하기가 쉽지 않다. 관찰대상이 되는 클래스를 정의하기 위해서는 java.util.Observable 클래스를 상속받아야 한다. 그런데, 이미 Subject 역할로 생각하고 있는 클래스가 다른 클래스의 하위 클래스이면, Observable 클래스를 또 상속 받을 수가 없다. (왜냐하면, 다중 상속을 자바는 지원하지 않으므로) 따라서, 사용하기가 쉽지 않다. public void update(Observable obj, Object arg) 부가 정보 관찰되는 대상 /42

20 06. 관련 패턴 Mediator 패턴 /42

21 객체의 상태변화를 다른 객체에게 통지하는 Observer 패턴
07. 요약 객체의 상태변화를 다른 객체에게 통지하는 Observer 패턴 /42

22 17-1 연습 문제 예제 프로그램에, 관찰대상으로서의 IncrementalNumberGenerator 클래스를 추가하기
시작하는 수와 마지막 수 및 증가분을 입력받는 생성자를 가진다. 예: new IncrementalNumberGenerator(10, 50, 5) 인 경우 10부터 50까지 5씩 증가하면서 숫자 생성 (10, 15, 20, ...) 숫자가 만들어질 때 마다 관찰자에게 통지한다. /42

23 17-2 연습 문제 startAngle 90 -number*360/50 (arcAngle) 예제 프로그램에 관찰자 3개를
17-2 예제 프로그램에 관찰자 3개를 추가함 FrameObserver BorderLayout 매니저: 프레임 영역을 동서남북중앙으로 나눔 update( ): GraphText와 GraphCanvas의 update( )를 호출함 GraphText 숫자만큼의 ‘*’를 출력하는 관찰자 GraphCanvas Graphics 객체의 fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) startAngle 부터 arcAngle 만큼 그린다 startAngle: 0 이면 3시 위치를 의미한다. (반시계방향으로 증가) arcAngle: 양수이면 반시계 방향으로 그리고, 음수이면 시계방향으로 그린다 /42

24 Homework #4: Observer 패턴 응용
예제 프로그램에 관찰자 및 관찰 대상 추가하기 관찰자 클래스: NamePrintObserver 관찰 대상자로부터 통지가 올 때 마다, 관찰 대상자로부터 숫자를 얻어 그 숫자만큼의 자기 이름을 새로운 한 줄에 계속해서 출력한다. 예: 관찰대상자로부터 얻은 숫자가 5 인 경우 출력: 최승훈 최승훈 최승훈 최승훈 최승훈 관찰대상 클래스: PrimeNumberGenerator NumberGenerator의 하위 클래스로 둔다 1부터 50 사이의 소수(prime number)를 생성한다 생성할 때 마다 등록된 관찰자들에게 통지한다. Main 클래스의 main( ) PrimeNumberGenerator 의 인스턴스인 png를 생성한다. DigitObserver와 GraphObserver 이외에 NamePrintObserver의 인스턴스를 생성한다. png에 위의 3가지 Observer를 등록한다. png.execute( )를 실행한다. 숙제 제출 방법: 이전 것과 똑같은 방법으로 제출함 /42


Download ppt "Java로 배우는 디자인패턴 입문 Chapter 17. Observer 패턴 상태의 변화를 통지한다"

Similar presentations


Ads by Google