본문 바로가기
back/Design Pattern

[Design pattern] Observer Pattern (옵저버패턴) 그리고 리스너

by 사용자 펭귄대장 2019. 11. 21.

옵저버 패턴에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의한다. (Head First Design Pattern 내용 발췌)

Subject(주제) 객체에 변화가 일어날 경우 Subject에 의존하고 있는 다수의 Observer 에 변화를 알리는 일대다 의존성을 갖는 디자인 패턴. 대표적으로 java.awt 의 listener가 Observer pattern 이라고 할 수 있다.

 

Observer pattern 을 파악하기 위해

java.awt 의 lister 와 Button 을 어설프게나마 직접 구현해보자.

 

[Listener]

Observer 와 같은 역할을 하는 Listener Interface

1
2
3
4
5
6
package design_pattern.observer;
 
public interface Listener {
    public void performAction();
}
 
cs

 

[CustomListener1]

Observer 를 구현한 CustomListener1

performAction() 은 주제 객체의 변화가 일어났을 때 호출이 되는 메소드

1
2
3
4
5
6
7
8
9
package design_pattern.observer;
 
public class CustomListener1 implements Listener {
    @Override
    public void performAction() {
        System.out.println("custom listener1 perform action !");
    }
}
 
cs

 

[Component]

주제 인터페이스 Component

1
2
3
4
5
6
7
8
package design_pattern.observer;
 
public interface Component {
    public void addListener(Listener l);
    public void removeListener(Listener l);
    public void notifyListeners();
}
 
cs

 

[Button]

주제 인터페이스를 구현한 주제 객체 Button

Observer 역할을 하는 listeners 를 멤버변수로 갖고 있다(구상)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package design_pattern.observer;
 
import java.util.ArrayList;
 
public class Button implements Component {
    
    private ArrayList<Listener> listeners;
    
    public Button() {
        this.listeners = new ArrayList<Listener>();
    }
    
    @Override
    public void addListener(Listener l) {
        listeners.add(l);
        System.out.println("listener added!");
    }
 
    @Override
    public void removeListener(Listener l) {
        int idx = listeners.indexOf(l);
        listeners.remove(idx);
        System.out.println("listener removed!");
    }
 
    @Override
    public void notifyListeners() {
        for(Listener l : listeners) {
            l.performAction();
        }
    }
    
    public void buttonClicked() {
        notifyListeners();
    }
    
}
 
cs

 

[Main]

Listener 를 익명클래스로 구현 후 customListeners2 변수로 선언하였다.

Listener(Observer) 두개를 Button(주제) 객체에 등록(addListener)해주었고,

실제 Button 을 클릭 해 볼 수 없으니,

마치 버튼을 클릭 한 것 처럼 버튼객체의 buttonClicked() 메소드를 호출해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package design_pattern.observer;
 
import java.awt.TextField;
import java.awt.event.ActionListener;
 
public class Main {
 
    public static void main(String[] args) {
        
        Button btn = new Button();
        
        Listener customListener1 = new CustomListener1();
        
        Listener customListener2 = new Listener() {
            @Override
            public void performAction() {
                System.out.println("custom listener2 perform action !");
            }
        };
        
        btn.addListener(customListener1);
        btn.addListener(customListener2);
        
        btn.buttonClicked();
        
        System.out.println("----------------------------");
        
        btn.removeListener(customListener2);
        
        System.out.println("----------------------------");
        btn.buttonClicked();
        
    }
    
}
 
cs

 

실행 결과

listener added!
listener added!
custom listener1 perform action !
custom listener2 perform action !
----------------------------
listener removed!
----------------------------
custom listener1 perform action !

 

반응형

댓글0