관찰자 모드 테스트

25057 단어 관찰자 모드
관찰자 모델 은 구독 - 발표 모델 이 라 고도 부 르 며 매우 자주 사용 하 는 디자인 모델 중 하나 이다.
소개
먼저 의 소 개 를 살 펴 보 자. 대상 간 의 다 중 의존 관 계 를 정의 하 는 것 이다.대상 의 상태 가 바 뀌 었 을 때 그 대상 에 의존 하 는 모든 대상 이 알림 을 받 고 자동 으로 업 데 이 트 됩 니 다.
관찰자 모드 의 본질: 트리거 연동.
무슨 뜻 이 죠?한 대상 의 상태 가 바 뀌 면 다른 대상 이 자동 으로 응답 한 다 는 것 이다.어떻게 하면 목표 대상 의 상태 가 바 뀔 때 관찰자 대상 이 자동 으로 응답 할 수 있 습 니까?
간단 합 니 다. 목표 대상 에 게 관찰자 대상 을 가지 게 하면 됩 니 다.만약 에 한 목표 대상 에 여러 명의 관찰자 가 있 으 면 목표 대상 의 상태 가 바 뀔 때마다 자신 이 가지 고 있 는 관찰자 대상 을 자동 으로 옮 겨 다 니 며 자신의 상태 가 바 뀐 상황 을 관찰자 에 게 알 리 는 것 이 바로 파 라 메 터 를 관찰자 에 게 전달 하 는 것 이다.관찰자 의 패턴 은 단지 이렇다.
나의 박문 중개 자 모드 테스트 을 참고 하면 관찰자 모델 과 중개자 모델 이 비슷 한 점 이 많다 는 것 을 알 수 있다.구성 요소 간 에 정 보 를 전달 할 때 도 자신 을 전달 하고 처리 할 때 강제 형식 변환 을 사용 하여 처리 합 니 다.그러나 중개 자 는 보통 여러 개의 구성 요소 류 가 자신 을 대리 류 에 전달 하여 대리 류 가 구성 요소 간 의 상호작용 을 통일 적 으로 처리 하도록 한다.한편, 관찰자 모델 은 반대로 목표 류 가 바 뀌 었 을 때 자신 이 가지 고 있 는 모든 관찰자 에 게 자신 을 전달 하면 관찰자 의 방법 을 활성화 시킨다.
 
2. 나의 실현
스윙 에는 대량의 관찰자 모델 의 실현 이 포함 되 어 있다.이해 하기 편 하도록 저도 스윙 을 따라 하 겠 습 니 다.우 리 는 모두 화판 에 그림 을 그 리 는 것 을 알 고 있다. 매번 화판 에서 마우스 왼쪽 단 추 를 클릭 할 때마다 화판 에 해당 하 는 점 이 나 타 났 다.붙 잡 고 놓 지 않 으 면 선 을 그 릴 수 있다.왜 그 럴 까요?우 리 는 패 널 을 목표 대상 으로 삼 아 감청 기 가 있다 고 가정 했다.왼쪽 단 추 를 누 를 때마다 이벤트 가 발생 합 니 다. 패 널 은 바로 이 사건 을 받 아들 이 고 처리 한 후에 모니터 에 전달 하고 모니터 가 그 려 줍 니 다.
내 가 모 의 하려 는 것 은 바로 이 과정 이다.다음 과 같다.
1. 추상 적 인 목표 유형:
//      

public abstract class Subject {



    //     

    protected List<Listener> listenerList = new ArrayList<Listener>();



    //     

    public void addListener(Listener listener)

    {

        listenerList.add(listener);

    }



    //     

    public void removeListener(Listener listener)

    {

        listenerList.remove(listener);

    }



    //       

    abstract void notifyListener();

}

2. 모니터 는 표지 인터페이스 일 뿐 그 어떠한 방법 도 실현 하지 못 한다.
public interface Listener {

}

3. 이벤트 가 발생 하 는 요 소 를 패키지 하여 이벤트 클래스 가 됩 니 다. 마우스 이 벤트 는 다음 과 같 습 니 다.
//      

public class MouseEvent {



    //     、 、  

    public static final int BUTTON1 = 1;

    public static final int BUTTON2 = 2;

    public static final int BUTTON3 = 3;

    private int x;

    private int y;

    private int ClickCount;

    

    public int getClickCount()

    {

        return ClickCount;

    }



    public void setClickCount(int clickCount)

    {

        ClickCount = clickCount;

    }



    public int getX()

    {

        return x;

    }



    public void setX(int x)

    {

        this.x = x;

    }



    public int getY()

    {

        return y;

    }



    public void setY(int y)

    {

        this.y = y;

    }



}

4. 매번 마우스 이벤트 에서 마우스 위 치 를 꺼 내 화면의 점 으로 밀봉 해 야 합 니 다. PointOnScreen 류 는 다음 과 같 습 니 다.
public class PointOnScreen {



    private int x;

    private int y;



    public int getX()

    {

        return x;

    }



    public void setX(int x)

    {

        this.x = x;

    }



    public int getY()

    {

        return y;

    }



    public void setY(int y)

    {

        this.y = y;

    }



}

5. 시스템 모니터 로 표지 인터페이스 Listener 를 실현 했다.
//     

public class SystemListener implements Listener {

    //             

    public void drawOnScreen(List<PointOnScreen> graph)

    {

        System.out.println();

        System.out.println("    :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

        for (PointOnScreen point : graph)

        {

            System.out.println("       ——————(" + point.getX() + "," + point.getY() + ")");

        }

    }

}

6. 다음은 가장 중요 한 목표 의 구체 적 인 유형 인 화판 류 입 니 다.
public class Panel extends Subject {



    //     

    private List<PointOnScreen> graph = new ArrayList<PointOnScreen>();



    //       

    public void addKeyEvent(MouseEvent event)

    {

        //       

        PointOnScreen point = new PointOnScreen();

        point.setX(event.getX());

        point.setY(event.getY());

        graph.add(point);

        //        

        notifyListener();

    }



    @Override

    void notifyListener()

    {

        //      PanelListener,  !

        for (Listener listener : listenerList)

        {

            if (listener instanceof SystemListener)

            {

                ((SystemListener) listener).drawOnScreen(graph);

            }

        }

    }



}

7. 이로써 완성 되 었 습 니 다. 테스트 해 보 겠 습 니 다.
public class Test {



    public static void main(String[] args)

    {

        //  MouseEvent,      

        MouseEvent event1 = new MouseEvent();

        event1.setX(1);

        event1.setY(2);

        MouseEvent event2 = new MouseEvent();

        event2.setX(2);

        event2.setY(2);

        MouseEvent event3 = new MouseEvent();

        event3.setX(2);

        event3.setY(3);

        

        //     

        Panel panel = new Panel();

        

        //     

        SystemListener autoListener = new SystemListener();

        

        //     

        panel.addListener(autoListener);

        

        //

        panel.addKeyEvent(event1);

        panel.addKeyEvent(event2);

        panel.addKeyEvent(event3);

    }

}

8. 결 과 는 다음 과 같다.
    :2014-04-29 15:44:26.546

       ——————(1,2)



    :2014-04-29 15:44:26.548

       ——————(1,2)

       ——————(2,2)



    :2014-04-29 15:44:26.548

       ——————(1,2)

       ——————(2,2)

       ——————(2,3)

위 와 같이 그림 을 그 리 는 과정 을 모 의 해 냈 다.
 
3. 푸 시 모델 과 당 김 모델
무엇이 푸 시 모델 과 당 김 모델 입 니까?위의 예 에서 사건 의 근원 은 무엇 입 니까?마우스 이벤트 입 니 다.그러나 모니터 대상 에 게 전 달 될 때 우 리 는 Mouse Event 를 PointOnScreen 대상 으로 포장 하여 전달 했다.이것 이 바로 푸 시 모형 이다.
상대 적 으로 당 김 모델 은 정 보 를 모니터 에 전달 할 때 자체 의 인용 을 전달 하 는 것 을 말한다. 그러면 모니터 대상 이 원 하 는 정 보 를 처리 하 는 것 이 바로 당 김 모델 이다.
우 리 는 Panel 을 바 꿀 것 이다.
public class Panel extends Subject {



    //     

    private List<PointOnScreen> graph = new ArrayList<PointOnScreen>();



    private KeyEvent keyEvent;

    

    public KeyEvent getKeyEvent(){

        return keyEvent;

    }

    

    //       

    public void addKeyEvent(MouseEvent event)

    {

        //       

        PointOnScreen point = new PointOnScreen();

        point.setX(event.getX());

        point.setY(event.getY());

        graph.add(point);

        //        

        notifyListener();

    }



    void notifyListener(){

        for (Listener listener : listenerList)

        {

            if (listener instanceof SystemListener)

            {

                //        

                listener.update(this);

            }

        }

    }

}

그리고 SystemListener 를 이렇게 만 듭 니 다.
//     

public class SystemListener implements Listener {

    //             

    public void drawOnScreen(List<PointOnScreen> graph)

    {

        System.out.println();

        System.out.println("    :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

        for (PointOnScreen point : graph)

        {

            System.out.println("       ——————(" + point.getX() + "," + point.getY() + ")");

        }

    }



    //     

    private List<PointOnScreen> graph = new ArrayList<PointOnScreen>();



    public void update(Subject subject)

    {

        if (subject instanceof Panel)

        {

            MouseEvent event = ((Panel) subject).getMouseEvent();

            //       

            PointOnScreen point = new PointOnScreen();

            point.setX(event.getX());

            point.setY(event.getY());

            graph.add(point);

            drawOnScreen(graph);

        }

    }



}

위 와 같이 대상 이 정 보 를 전달 할 때 자신 을 전달 하고 모니터 가 정 보 를 처리 할 때 필요 한 것 은 대상 에 게 서 가 져 가 는 것 이 편리 하 다.이것 이 바로 당 김 모형 이다.
 
4. 자바 의 관찰자 모드
관찰자 모델 을 실현 하려 면 사실 그렇게 번 거 롭 지 않 아 도 된다. 목표 류 와 감청 자 인터페이스 자바 가 우 리 를 도와 실현 했다.대상 클래스 는 java. util. Observable 이 고 모니터 인 터 페 이 스 는 java. util. Observer 입 니 다.
즉, 목표 클래스 는 java. util. Observable 을 계승 하고 감청 기 인 터 페 이 스 는 java. util. Observer 를 실현 해 야 한다.어떻게 값 을 전달 합 니까?
목표 클래스 상태 가 바 뀌 면 다음 과 같은 몇 가지 방법 을 사용 합 니 다.
        //    

        this.keyEvent = event;

        //

        this.setChanged();

        //    

        this.notifyObservers();

        //        

        this.notifyObservers(graph);    

이 동시에 모니터 인 터 페 이 스 는 이런 방법 을 실현 했다.
  public void update(Observable o, Object arg)

    {

        //     o

        //     arg

    }

아주 간단 해!
다음은 자바 의 관찰자 모드 로 예 를 들 어 보 겠 습 니 다.
1. 목표 유형 은 다음 과 같다.
public class Panel extends java.util.Observable {



    //     ,     

    private List<PointOnScreen> graph = new ArrayList<PointOnScreen>();

    

    private MouseEvent keyEvent;

    

    public MouseEvent getMouseEvent(){

        return keyEvent;

    }

    

    //       

    public void addKeyEvent(MouseEvent event)

    {   //    

        this.keyEvent = event;

        //

        this.setChanged();

        //    

        this.notifyObservers();

        

        //

        PointOnScreen point = new PointOnScreen();

        point.setX(event.getX());

        point.setY(event.getY());

        graph.add(point);

        //        

        this.notifyObservers(graph);

    }

}

2. 모니터 류 는 다음 과 같다.
//     

public class SystemListener  implements java.util.Observer {

    //             

    public void drawOnScreen(List<PointOnScreen> graph)

    {

        System.out.println();

        System.out.println("    :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

        for (PointOnScreen point : graph)

        {

            System.out.println("       ——————(" + point.getX() + "," + point.getY() + ")");

        }

    }



    //     

    private List<PointOnScreen> graph = new ArrayList<PointOnScreen>();



    @Override

    public void update(Observable o, Object arg)

    {

        if (o instanceof Panel)

            

        {

            MouseEvent event = ((Panel) o).getMouseEvent();

            //       

            PointOnScreen point = new PointOnScreen();

            point.setX(event.getX());

            point.setY(event.getY());

            graph.add(point);

            drawOnScreen(graph);

        }

        

        //   

        List<PointOnScreen> graph = (ArrayList<PointOnScreen>)arg;

        drawOnScreen(graph);

    }



}

 

좋은 웹페이지 즐겨찾기