디자인 패턴에 대한 잡담(15) - 관찰자 패턴

칼럼 소개

열 주소

링크

칼럼 소개

주로 현재 시중에 나와 있는 23가지 공통 디자인 패턴을 하나씩 분석하고 요약한 책이니, 관심 있는 친구들이 한 번 살펴보고 지속적으로 업데이트되길 바란다. 저를 감독해 주시고 함께 배우고 발전할 수 있기를 바랍니다.
여기에 이미지 설명을 삽입하세요.

관찰자 패턴

관찰자 패턴(Observer Pattern)은 여러 관찰자 객체가 특정 토픽 객체를 동시에 모니터링할 수 있도록 하는 일대다 종속 관계를 정의하는 행위 디자인 패턴으로, 토픽 객체가 변경되면 해당 관찰자 모두에게 통보되고 스스로 업데이트됩니다.

여기에 이미지 설명을 삽입하세요.

주요 아이디어

관찰자와 관찰 대상 간의 종속성을 분리하여 서로 독립적으로 변경될 수 있도록 합니다. 관찰자는 관찰자가 특정 인터페이스를 구현한다는 것만 알면 되고 특정 관찰자 클래스를 알 필요는 없으며, 마찬가지로 관찰자는 관찰자가 특정 인터페이스를 구현한다는 것만 알면 되고 특정 관찰자를 알 필요는 없습니다. 수업. .
여기에 이미지 설명을 삽입하세요.

주인공

주제

관찰자 등록, 관찰자 ​​제거, 관찰자에게 알리기 위한 메서드를 포함한 관찰자의 인터페이스를 정의합니다.

ConcreteSubject (특정 관찰자)

관찰된 인터페이스를 구현하고 관찰자 목록을 유지하며 상태가 변경되면 관찰자에게 알립니다.

관찰자

관찰된 것으로부터 알림을 받기 위한 업데이트 방법을 포함하여 관찰자의 인터페이스를 정의합니다.

ConcreteObserver (콘크리트 관찰자)

관찰자 인터페이스를 구현하며, 구체적으로 업데이트 메소드를 구현하고, 관찰자로부터 알림을 받을 때 해당 처리를 수행합니다.
여기에 이미지 설명을 삽입하세요.

자바 프로그램 구현

// 定义观察者接口
interface Observer {
    
    
    void update(String message);
}

// 定义被观察者接口
interface Subject {
    
    
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String message);
}

// 具体观察者类
class ConcreteObserver implements Observer {
    
    
    private String name;

    public ConcreteObserver(String name) {
    
    
        this.name = name;
    }

    @Override
    public void update(String message) {
    
    
        System.out.println(name + " received message: " + message);
    }
}

// 具体被观察者类
class ConcreteSubject implements Subject {
    
    
    private List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
    
    
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
    
    
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
    
    
        for (Observer observer : observers) {
    
    
            observer.update(message);
        }
    }
}

// 测试代码
public class ObserverPatternExample {
    
    
    public static void main(String[] args) {
    
    
        ConcreteSubject subject = new ConcreteSubject();
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        subject.notifyObservers("Hello, observers!");

        subject.removeObserver(observer2);

        subject.notifyObservers("Observer 2 has been removed!");

    }
}

출력 결과

Observer 1 received message: Hello, observers!
Observer 2 received message: Hello, observers!
Observer 1 received message: Observer 2 has been removed!

프로그램 분석

위의 예에서는 관찰자 인터페이스(Observer)와 관찰된 인터페이스(Subject)를 정의했습니다. 구체적인 관찰자 클래스(ConcreteObserver)와 구체적인 관찰 클래스(ConcreteSubject)는 해당 인터페이스를 구현합니다.
여기에 이미지 설명을 삽입하세요.

장점과 단점 분석

이점

디커플링

관찰자 패턴은 관찰자와 관찰 대상 간의 종속성을 분리하여 독립적으로 변경할 수 있습니다. 관찰된 객체가 변경되면 어떤 관찰자가 존재하는지 알지 못한 채 관찰자에게 알리기만 하면 됩니다.

확장성

관찰자 패턴을 사용하면 관찰된 코드를 수정하지 않고도 새 관찰자를 쉽게 추가할 수 있습니다. 이는 개방형-폐쇄형 원칙을 준수하여 시스템을 더욱 유연하고 확장 가능하게 만듭니다.

일대다 관계

관찰자 패턴은 일대다 종속성을 구현할 수 있으며 관찰된 개체는 여러 관찰자를 가질 수 있습니다. 이를 통해 이벤트 모니터링, 메시지 구독 등의 기능을 쉽게 구현할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

결점

관찰자가 너무 많음

관찰자가 너무 많으면 관찰자가 관찰자에게 이를 알리는 데 오랜 시간이 걸릴 수 있으며 이는 시스템 성능에 영향을 미칩니다.

순환 의존성

관찰자와 관찰자 사이에 순환 종속성이 있으면 교착 상태와 같은 시스템 문제가 발생할 수 있습니다.

업데이트 주문 문제

관찰자 패턴에서는 관찰자의 업데이트 순서가 정의되지 않아 관찰자 간의 종속성 문제가 발생할 수 있습니다.

요약하다

이는 시스템의 유연성과 확장성을 향상시킬 수 있습니다. 하지만 동시에 시스템의 안정성과 성능을 보장하기 위해 너무 많은 관찰자, 순환 종속성, 업데이트 순서 등의 문제에도 주의를 기울여야 합니다. 관찰자 패턴을 사용할 때는 특정 시나리오와 요구 사항에 따라 절충과 디자인을 수행해야 합니다.

추천

출처blog.csdn.net/weixin_74888502/article/details/133525379