티스토리 뷰

반응형

옵저버 패턴 (Observer Pattern)


옵저버 패턴은 개개체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드를 통하여 관찰 대상자가 직접 옵저버들에게 통지하여 상태를 동기화 할 수 있도록 하는 디자인 패턴을 의미합니다.

 

옵저버 패턴 예제


옵저버 패턴이 적용된 예제를 구현 해보겠습니다.

Generator : 관찰 대상자를 나타내며, 현재 관찰 대상자에 붙어있는 Observer들을 관리합니다. 뿐만 아니라 현재 관찰 대상자의 상태 정보를 얻기 위한 메서드를 제공하며, 상태 변화시 등록되어 있는 모든 관찰자들에게 상태 변화를 통지해주는 메서드를 제공합니다.

 

StringGenerator : Generator를 상속받는 실제 상태 정보를 가지고 있는 객체입니다. 상태 변화가 발생하면 상태 변화를 통지해주는 메서드를 호출하게 됩니다.

 

Observer : 관찰자들이 가져야 할 공통인터페이스를 정의합니다.

 

StringObserver : 관찰 대상자의 상태 정보를 가져와 자신의 상태와 동기화 합니다. 이 객체는 관찰 대상자의 String형을 모니터에 출력해주는 객체입니다.

 

StringCountObsever : 마찬가지로 관찰 대상자의 상태 정보를 가져와 자신의 상태와 동기화 합니다. 이 객체는 관찰 대상자인 String형 문자열의 개수를 화면에 출력해주는 객체입니다.

 

구현


Generator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public abstract class Generator {
    //등록된 옵저버들을 관리하기 위한 ArrayList
    private ArrayList<Observer> observers = new ArrayList<Observer>();
 
    public void AddObserver(Observer observer)    //옵저버 등록
    {
        observers.add(observer);
    }
 
    public void NotifyObservers()                //상태 변화에 따른 옵저버들에게 통지해주는 메서드
    {
        for(int i=0;i<observers.size();i++)
        {
            observers.get(i).update(this);
        }
    }
    public abstract String getString();
    public abstract void execute();
}

▶ 관찰 대상자에 해당하는 Generator 클래스입니다. 관찰 대상자에 등록되는 Observer들을 관리하기 위한 ArrayList와 관리하기 위한 메서드를 제공을 합니다. 또한, 등록되어 있는 Observer들의 update() 메서드를 호출함으로써 관찰 대상자의 상태 변화를 통지를 해주는 NotifyObservers() 메서드를 제공합니다.

 

StringGenerator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class StringGenerator extends Generator{
    
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    
    private String Message;        //상태 정보를 가지는 String형 변수
    public String getString()    //현재 관찰 대상자의 상태 정보를 반환
    {
        return this.Message;
    }
    public void execute()
    {
        while(true)
        {
            try {
                Message = in.readLine();    //키보드 입력이 있었다는 건 상태 정보가 변한 것을 의미
                NotifyObservers();            //등록된 옵저버들에게 통지
            }catch(Exception e) {}
        }
    }
}

실제로 상태 정보를 가지는 StringGenerator 클래스입니다. 상태 정보는 String형 변수인 Message로 사용자의 키보드 입력을 저장하는 변수입니다. 즉, 사용자가 키보드 입력이 발생한다는건 상태 정보가 변하는 것을 의미하므로 NotifyObservers() 메서드를 호출함으로써 옵저버들에게 통지를 해줍니다.

 

Observer

1
2
3
public interface Observer {
    public void update(Generator generator);  //관찰 대상자와 상태 정보를 동기화
}

▶옵저버들이 공통적으로 가져야 할 인터페이스를 정의합니다. update() 메서드는 상태 변화를 통지 받은 옵저버가 자신의 상태를 관찰 대상자와 동기화 시키는 메서드입니다.

 

StringObserver

1
2
3
4
5
6
7
8
public class StringObserver implements Observer {
    String Message;
    public void update(Generator generator)
    {
        Message = generator.getString();        //관찰 대상자의 상태정보를 가져옴
        System.out.println("StringObserver : " + Message); //화면에 출력
    }
}

옵저버들중 하나로 관찰 대상자의 String형 데이터를 화면에 출력해주는 옵저버입니다. update()에서 관찰 대상자의 상태 정보를 가져와 자신의 상태를 관찰 대상자의 상태와 동기화하고 있습니다.

 

StringCountObserver

1
2
3
4
5
6
7
8
public class StringCountObserver implements Observer {
    int count;
    public void update(Generator generator)
    {
        count = generator.getString().length();        //관찰 대상자의 상태 정보를 가져와 문자열 길이를 저장
        System.out.println("StringCountObserver : " + count);
    }
}

옵저버들중 하나로 관찰 대상자의 문자열 길이를 화면에 출력해주는 옵저버입니다.

 

반응형