观察者模式简介

这篇具有很好参考价值的文章主要介绍了观察者模式简介。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概念:

观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,其相关依赖对象会自动收到通知并进行相应处理。

特点:

  1. 松耦合:主题和观察者之间通过抽象接口进行交互,使得它们可以独立演化而不影响彼此。
  2. 一对多关系:一个主题可以有多个观察者,并且它们之间没有直接联系。
  3. 可扩展性:可以随时增加新的观察者或删除现有观察者。

优点:

  1. 解耦合:将主题与具体观察者解耦,使得它们可以独立地变化和复用。
  2. 扩展性:易于添加新的观察者以及定义新的事件类型。
  3. 实时性:实现了实时更新机制,当主题状态改变时能够即刻通知相关观察者。

缺点:

  1. 过度使用可能导致性能问题和复杂度增加。
  2. 触发链问题:如果观察者之间有依赖关系,那么通知链可能会导致不可预料的结果。

适用场景:

  1. 当一个对象的改变需要同时影响其他多个对象时。
  2. 当系统中存在一些对象之间的联动行为,但又希望它们之间解耦合时。

实现方式

使用自定义接口

主题和观察者都实现相应接口,在主题中维护一个观察者列表,并在状态改变时遍历通知所有观察者。

实现原理:

  1. 定义一个观察者接口(Observer),其中声明了一个更新方法(update)用于接收主题状态的改变。
  2. 定义一个主题接口(Subject),其中包括添加观察者、移除观察者和通知观察者等方法。
  3. 创建具体的主题类(ConcreteSubject),该类维护了一个观察者列表,并在状态改变时遍历通知所有注册的观察者。
  4. 创建具体的观察者类(ConcreteObserver),该类实现了更新方法,在收到主题通知时进行相应操作。

实现代码:

import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
    void update(String newState);
}

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体主题类
class ConcreteSubject implements Subject {
    
    private List<Observer> observers = new ArrayList<>();
    private String state;
    
    public void setState(String newState) {
        this.state = newState;
        notifyObservers();
    }
    
   @Override 
   public void registerObserver(Observer observer) { 
       observers.add(observer); 
   } 

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

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

// 具体观察者类
class ConcreteObserver implements Observer {

    private String observerState;
    
    @Override
    public void update(String newState) {
        this.observerState = newState;
        // 执行相应操作
        System.out.println("Observer state updated: " + observerState);
    }
}

// 使用示例
public class Main {
   public static void main(String[] args) {
       ConcreteSubject subject = new ConcreteSubject();
       
       Observer observer1 = new ConcreteObserver();
       Observer observer2 = new ConcreteObserver();
       
       subject.registerObserver(observer1);
       subject.registerObserver(observer2);
       
       subject.setState("New State");
   }
}

上述代码中,我们定义了一个观察者接口 Observer,其中包括了一个更新方法 update。然后,我们定义了一个主题接口 Subject,其中包括注册观察者、移除观察者和通知观察者等方法。接着,我们创建了具体的主题类 ConcreteSubject,该类维护了一个观察者列表,并在状态改变时遍历通知所有注册的观察者。最后,我们创建了具体的观察者类 ConcreteObserver 实现更新方法,在收到主题通知时执行相应操作。

使用自定义接口实现方式的问题:

  1. 主题与具体观察者之间存在紧耦合关系。
  2. 观察者可能无法感知到其他已注册的新类型或特定类型。

尽管存在以上问题,使用自定义接口实现方式是观察者模式的经典实现方式,并且具有简单、直观的特点。

使用Java内置Observable类和Observer接口

主题继承Observable类并调用其方法进行状态改变通知,观察者实现Observer接口并注册到主题上。

实现原理:

  1. 创建一个具体主题类(ConcreteSubject),该类继承自Observable类。
  2. 在具体主题类中定义状态改变方法,并在该方法中调用setChanged()和notifyObservers()方法来通知所有注册的观察者。
  3. 创建一个具体观察者类(ConcreteObserver),该类实现了Observer接口,并在update()方法中定义观察者收到通知后的操作。

实现代码:

import java.util.Observable;
import java.util.Observer;

// 具体主题类
class ConcreteSubject extends Observable {

    private String state;
    
    public void setState(String newState) {
        this.state = newState;
        setChanged();
        notifyObservers(state);
    }
}

// 具体观察者类
class ConcreteObserver implements Observer {

    private String observerState;
    
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof ConcreteSubject) {
            this.observerState = (String) arg;
            // 执行相应操作
            System.out.println("Observer state updated: " + observerState);
        }
    }
}

// 使用示例
public class Main {
   public static void main(String[] args) {
       ConcreteSubject subject = new ConcreteSubject();
       
       Observer observer1 = new ConcreteObserver();
       Observer observer2 = new ConcreteObserver();
       
       subject.addObserver(observer1);
       subject.addObserver(observer2);
       
       subject.setState("New State");
   }
}

上述代码中,我们创建了一个具体主题类 ConcreteSubject,该类继承自Java内置的Observable类。在该类中,我们定义了状态改变方法 setState(),并在该方法中调用setChanged()notifyObservers()来通知所有注册的观察者。

然后,我们创建了一个具体观察者类 ConcreteObserver 实现Observer接口,并在update()方法中定义观察者收到通知后的操作。

最后,在使用示例中,我们创建了一个具体主题对象和两个具体观察者对象,并将观察者注册到主题上。当主题状态改变时,会自动通知所有注册的观察者进行相应操作。使用Java内置ObservableObserver实现方式存在以下问题:

  1. Observable是一个类而不是接口,因此无法继承其他父类。
  2. Observable被标记为已过时,虽然仍可使用但不推荐使用。
  3. 观察者只能通过实现Observer接口来实现与主题的交互。

尽管存在以上问题,使用Java内置ObservableObserver实现方式可以更方便地利用已有工具来快速实现观察者模式。

使用事件机制

通过定义事件类、监听器接口以及注册监听器等方式来实现观察者模式。当事件发生时,主题发布该事件给已注册的监听器。

实现原理:

  1. 定义一个事件类(Event),该类包含了需要传递给观察者的数据。
  2. 创建一个主题类(Subject),其中包括注册观察者、移除观察者和触发事件等方法。
  3. 创建一个具体主题类(ConcreteSubject),该类继承自主题类,在具体主题中定义了相应的业务逻辑,并在合适的时机通过调用触发事件方法来通知所有注册的观察者。
  4. 创建一个接口或抽象类作为基础,定义了处理特定类型事件的方法,然后创建具体的处理器类,实现这些方法以执行相应操作。
  5. 观察者根据所需监听的特定类型事件来实现对应接口或抽象类,并在其方法内进行相应操作。

实现代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 事件类
class Event {
    private String eventType;
    private Map<String, Object> eventData = new HashMap<>();

    public Event(String eventType) {
        this.eventType = eventType;
    }

    public String getEventType() {
        return eventType;
    }

    public void addData(String key, Object value) {
        eventData.put(key, value);
    }

    public Object getData(String key) {
        return eventData.get(key);
    }
}

// 主题接口
interface Subject {
   void registerObserver(Observer observer, String eventType);
   void removeObserver(Observer observer, String eventType);
   void notifyObservers(Event event);
}

// 具体主题类
class ConcreteSubject implements Subject {
    private Map<String, List<Observer>> observersMap = new HashMap<>();

    @Override
    public void registerObserver(Observer observer, String eventType) {
        List<Observer> observers = observersMap.getOrDefault(eventType, new ArrayList<>());
        observers.add(observer);
        observersMap.put(eventType, observers);
    }

    @Override
    public void removeObserver(Observer observer, String eventType) {
        if (observersMap.containsKey(eventType)) {
            List<Observer> observes = observersMap.get(eventType);
            observes.remove(observer);

            if (observes.isEmpty()) { // 若没有观察者监听该事件,则从观察者列表中移除该事件类型
                observersMap.remove(eventType); 
            }
        }
    }

   @Override   
   public void notifyObservers(Event event) {  
       if (event != null && event.getEventType() != null && 
           observersMap.containsKey(event.getEventType())) {

           for (Observer observe : observersMap.get(event.getEventType())) {   
               observe.onEventReceived(event);  
           }    
       } 
   }
}

// 观察者接口
interface Observer {
  void onEventReceived(Event event);  
}

// 具体观察者类1,处理特定类型事件的处理器之一
class ConcreteHandler1 implements Observer {

  @Override   
  public void onEventReceived(Event event) {    
      if ("eventType1".equals(event.getEventType())) {     
          // 执行相应操作       
          System.out.println("ConcreteHandler1 received Event: " + event.getData("data"));     
      }      
  } 
}

// 具体观察者类2,处理特定类型事件的处理器之一
class ConcreteHandler2 implements Observer {

  @Override   
  public void onEventReceived(Event event) {    
      if ("eventType2".equals(event.getEventType())) {     
          // 执行相应操作       
          System.out.println("ConcreteHandler2 received Event: " + event.getData("data"));     
      }      
  }
}

// 使用示例
public class Main {
   public static void main(String[] args) {
       ConcreteSubject subject = new ConcreteSubject();
       
       Observer handler1 = new ConcreteHandler1();
       Observer handler2 = new ConcreteHandler2();
       
       subject.registerObserver(handler1, "eventType1");
       subject.registerObserver(handler2, "eventType2");
       
       Event event1 = new Event("eventType1");
       event1.addData("data", "Event data for eventType1");

        Event event2 = new Event("eventType2");
        event2.addData("data", "Event data for eventType2");

        subject.notifyObservers(event1);
        subject.notifyObservers(event2);
   }
}

上述代码中,我们定义了一个事件类 Event,其中包含了需要传递给观察者的数据。然后,我们创建了主题接口 Subject 和具体主题类 ConcreteSubject 来实现注册观察者、移除观察者和通知观察者等方法。

接着,我们定义了一个观察者接口 Observer ,并创建两个具体的处理器类(例如:ConcreteHandler1  `ConcreteHandler12)来实现对不同类型事件的监听和相应操作。

在使用示例中,我们创建了一个具体主题对象和两个具体观察者对象,并将观察者注册到主题上。当主题触发特定类型事件时,会自动通知对应的处理器进行相应操作。

使用事件机制实现方式可以更加灵活地处理不同类型的事件,并使得代码结构更清晰。文章来源地址https://www.toymoban.com/news/detail-683178.html

到了这里,关于观察者模式简介的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——14. 观察者模式

    观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能够自动收到通知并更新自己的状态,以保持与被观察对象的同步。观察者模式也被称为发布-订阅模式。 观察者模式包含以

    2024年02月07日
    浏览(34)
  • 设计模式之观察者模式

    可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。 从报纸和杂志的订阅说起: 报社的业务就是出版报纸 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。 当你不

    2024年01月24日
    浏览(41)
  • 重温设计模式 --- 观察者模式

    观察者模式 是一种行为型设计模式,它允许对象之间建立一种一对多的关系,使得当一个对象状态改变时,所有依赖它的对象都能够自动得到通知并更新自己的状态。该模式可以帮助我们实现松耦合的系统,以便更好地应对变化和扩展。 在观察者模式中,有两个角色: 观察

    2024年02月13日
    浏览(43)
  • 设计模式(11)观察者模式

    一、概述: 1、定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 2、结构图: 实现  调用

    2024年02月11日
    浏览(36)
  • 设计模式-观察者

    观察者模式是一种广泛应用于软件开发中的行为设计模式,尤其是在面向对象编程(OOP)中。该模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新 在观察者模式中,存在两个主要角色: 主题(Subject) 或 被

    2024年01月22日
    浏览(33)
  • 观察者设计模式

    行为型模式(Behavioral Patterns):这类模式主要关注对象之间的通信。它们 分别是: 职责链模式(Chain of Responsibility) 命令模式(Command) 解释器模式(Interpreter) 迭代器模式(Iterator) 中介者模式(Mediator) 备忘录模式(Memento) 观察者模式(Observer) 状态模式(State) 策略

    2024年01月24日
    浏览(35)
  • 设计模式:行为型模式 - 观察者模式

    定义: 又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 在观察者模式中有如下角色: Subject:抽象主题(抽象被观察

    2023年04月22日
    浏览(84)
  • 设计模式【行为型】-- 观察者模式

    观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一种一对多的依赖关系,使得当一个对象状态改变时,其相关依赖对象都能得到通知并自动更新。 主题( Subject ):也称为被观察者,它维护一个观察者列表,并提供添加、删除和通知观察者的方法。

    2024年02月15日
    浏览(40)
  • js设计模式:观察者模式

    和发布订阅模式基本类似。 当某一对象状态发生变化时,所有的观察者都会收到通知。 vue响应式原理就是很经典的案例,数据发生变化,通知各个依赖。

    2024年02月19日
    浏览(20)
  • 设计模式之二:观察者模式

    假定我们需要为Weather-O-Rama公司建立一个气象站系统,除已有的WeatherData有数据源类,还需要更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天气预报。  1 以下是一个可能的实现 上述实现有以下问题存在: 针对具体实现编程,而非针对接口(currentCon

    2024年02月13日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包