콜백과 관찰자 모드

5657 단어

관찰자 모드


관찰자 모델은 감청의 수요를 만족시키기 위한 것이다.즉, 어떤 일이 발생할 때 한 명 이상의 관찰자가 이 사건의 발생을 알아야 한다. 만약에 모든 관찰자가 윤문으로 사건의 발생 여부를 판단하면 비교적 많은 자원을 소모하게 된다.그래서 이 임무는 피관찰자가 완성해야 한다. 즉, 피관찰자가 여러 개의 관찰자 대상을 가지고 자신의 어떤 사건이 발생할 때 모든 관찰자에게 통지해야 한다.이런 메커니즘은 바로 관찰자 모델이다.
그러나 그 중에서 안전 문제가 있을 수 있다. 예를 들어 피관찰자가 관찰자의 대상을 가지고 있으면 이때 관찰자가 피관찰자에게 완전히 노출된다. 이런 상황은 발생을 피해야 한다.그래서 자연스럽게 인터페이스의 개념을 끌어내어 하나의 인터페이스로 관찰자의 행위를 통일시켰다. 피관찰자는 이 인터페이스만 가지고 있고 그 어떤 인터페이스가 실현된 대상도 관찰자로서 보유할 수 있지만 대상의 다른 세부 사항은 피관찰자에게 개방되지 않는다.자바에는 관찰자 모드가 봉인되어 있습니다. 우리는 그 묘사법을 본떠서 자신의 관찰자 모드를 실현할 수 있습니다. 우선, 우리가 앞서 언급한 바와 같이 관찰자는 관찰자가 호출할 수 있도록 통일된 인터페이스를 제공해야 합니다. 즉, Observer입니다.
public interface Observer {
    void update(Observable observable, Object object);
}

관찰자의 경우 비교적 복잡하기 때문에 우리는 몇 가지 주요한 절차를 찾아낼 수 있다.
번호
단계
1
소지 관찰자
2
변화 여부를 판단하다
3
관찰자에게 알리기
이렇게 하면 우리는 피관찰자의 추상적인 유형을 쓸 수 있다.
public abstract class Observable {

    private Vectorobservers = new Vector<>();
    private boolean isChanged;
    
    public void addObserver(Observer observer){
        observers.add(observer);
    }
    
    public void setChanged(){
        isChanged = true;
    }
    public void notifyObservers(Object object){
        if (isChanged) {
            observers.forEach(observer -> observer.update(this, object));
            isChanged = false;
        }
    }
}

이렇게 해서 우리는 관찰자의 인터페이스와 피관찰자의 추상류를 정의했다
사실 jdk의 실현에서 Observable는 완벽한 라인 안전 보호를 할 수 있다. 예를 들어 관찰자를 저장하는List는 Vector로 이루어진 것이고 Vector 자체는 라인 안전이다. 그리고 Observable의 방법에synchronize 표식부호를 추가하여 라인 안전한 방식으로 관찰자에게 통지한다.그러나 이것들은 여기서 모두 중점이 아니기 때문에 더 이상 상술하지 않겠다
다음은 실제 애플리케이션입니다.
우리의 예에서 한 명의 학생과 몇 명의 선생님이 있는데 학생들은 몇 가지 문제를 제기할 것이다. 이런 문제들은 선생님(관찰자에게 통지), 선생님은 자신이 할 수 있는지 판단하고 학생들에게 피드백을 줄 것이다.>여기서 우리는 두 명의 선생님이 있는데, 한 분은 수학 선생님이고, 한 분은 미술 선생님이다. 현재의 설정은 그들이 각자 한 문제만 대답하고, 나머지 문제에 부딪히면 건너뛰는 것이다.
구체적인 코드를 보십시오.
Tea_Math
public class Tea_Math implements Observer{

    private String name = " :";
    @Override
    public void update(Observable observable, Object object) {
        String question = (String) object;
        if(question.equals(" ?")){
            System.out.println(name +" ,  ");
        }else {
            System.out.println(name +" ,  ");
        }
        
    }
    
}

Tea_Art
public class Tea_Art implements Observer{

    private String name = " :";
    @Override
    public void update(Observable observable, Object object) {
        String question = (String) object;
        if(question.equals(" ?")){
            System.out.println(name +" ");
        }else {
            System.out.println(name +" ,  ");
        }
        
    }
    
}

Stu
public class Stu extends Observable{
    
    public void ask(String question){
        System.out.println("question:" + question);
        setChanged();
        notifyObservers(question);
    }
}

실제 호출:
public class Client {
    
    public static void main(String[] args) {
        
        Stu stu = new Stu();
        
        Tea_Math tea_Math = new Tea_Math();
        Tea_Art tea_Art = new Tea_Art();
        
        stu.addObserver(tea_Math);
        stu.addObserver(tea_Art);
        
        stu.ask(" ?");
        
        stu.ask(" ?");
    }
    
}

다음과 같은 결과를 살펴볼 수 있습니다.
question: 행렬 상승의 의미는 무엇입니까?
수학 선생님: 어떤 각도에서 보면 좌표의 변환 미술 선생님: 잘 모르겠어요. 다른 선생님한테 물어보세요.
question: 모네의 수련은 그의 만년 작품입니까?
수학 선생님: 잘 모르겠어요. 다른 선생님한테 물어봐요. 미술 선생님: 만년의 일련의 작품이에요.
이상은 관찰자 모델의 설명과 코드의 실현으로 비교적 명확해야 한다.

콜백:


리셋은 호출자의 수요를 만족시키기 위해 설계된 것이다.호출자가 어떤 동작을 실행해야 하고, 그 동작을 완성한 후에 무엇을 해야 할지 스스로 정의해야 한다.이때 이 동작은 호출자가 스스로 낸 것이지만 이 동작의 완성은 피호출자에게 맡겨야 한다. 그러면 호출자는 이 동작을 완성한 후에 다음에 무엇을 해야 하는지 어떻게 알아야 하는가?그것은 어떻게 해야만 호출자가 정의한 후속 작업을 알 수 있습니까?이때 리셋을 사용해야 한다. 리셋을 실현하는 기본적인 절차는 다음과 같다.
번호
단계
1
호출자가 어떤 동작을 정의합니다
2
그리고 이 동작을 수행할 피호출자를 지정합니다. (피호출자를 가지고 있습니다.)
3
작업이 완료된 후 수행해야 하는 후속 작업을 재정의합니다.
4
마지막으로 이 후속 동작을 피호출자에게 알린다(또는 이 후속 동작의 호출 방법을 피호출자에게 맡긴다고 할 수 있다).일반적인 상황에서 피호출자는 시스템 응용이다. 즉, 우리는 자신의 후속 동작을 시스템 응용에 알려주고 완성된 후에 우리의 조작을 실행하도록 한다.
클릭 이벤트의 실현으로 깊이 파고들 수 있다.
만약에 TextView가 호출자로서, On Click Listener가 호출자로서 TextView는 On Click Listener를 소지해야 하기 때문에 set On Click Listener 방법이 있고, On Click 동작을 실행해야 하기 때문에 클릭 방법이 있습니다.피호출자 OnclickListener에게 클릭 동작의 실제 완성자이기 때문에 온클릭 방법이 있다.이렇게 하면 양자의 구조를 쓸 수 있다.
TextView
public class TextView {
    private OnClickListener onClickListener;
    public void setOnClickListener(OnClickListener onClickListener){
        this.onClickListener = onClickListener;
    }
    public void click(){
        onClickListener.onClick("textview", 1);
    }
}

OnClickListener
public interface OnClickListener {
    void onClick(String view, int position);
}

실제 호출:
public class Client_Click {

    public static void main(String[] args) {
        TextView textView = new TextView();
        textView.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(String view, int position) {
                System.out.println(view);
                System.out.println(position);
            }
        });
        textView.click();
    }
}

위의 코드는 이미 비교적 명확해졌으니 리셋의 의미를 이해할 수 있을 것이다
리셋과 관찰자 모델의 관계와 차이, 그리고 그들의 적용 환경은 실제 상황과 결합하여 판단할 수 있다.나는 며칠 후에 시간이 있으면 상세하게 쓸 계획이다.

좋은 웹페이지 즐겨찾기