响应式网站开发原则,网站开发设计思想,wordpress社交媒体优化,官方网站welcome怎么注册概念#xff1a;
观察者模式#xff08;Observer Pattern#xff09;是一种行为型设计模式#xff0c;用于在对象之间建立一对多的依赖关系#xff0c;当一个对象的状态发生变化时#xff0c;其相关依赖对象会自动收到通知并进行相应处理。
特点#xff1a;
松耦合
观察者模式Observer Pattern是一种行为型设计模式用于在对象之间建立一对多的依赖关系当一个对象的状态发生变化时其相关依赖对象会自动收到通知并进行相应处理。
特点
松耦合主题和观察者之间通过抽象接口进行交互使得它们可以独立演化而不影响彼此。一对多关系一个主题可以有多个观察者并且它们之间没有直接联系。可扩展性可以随时增加新的观察者或删除现有观察者。
优点
解耦合将主题与具体观察者解耦使得它们可以独立地变化和复用。扩展性易于添加新的观察者以及定义新的事件类型。实时性实现了实时更新机制当主题状态改变时能够即刻通知相关观察者。
缺点
过度使用可能导致性能问题和复杂度增加。触发链问题如果观察者之间有依赖关系那么通知链可能会导致不可预料的结果。
适用场景
当一个对象的改变需要同时影响其他多个对象时。当系统中存在一些对象之间的联动行为但又希望它们之间解耦合时。
实现方式
使用自定义接口
主题和观察者都实现相应接口在主题中维护一个观察者列表并在状态改变时遍历通知所有观察者。
实现原理
定义一个观察者接口Observer其中声明了一个更新方法update用于接收主题状态的改变。定义一个主题接口Subject其中包括添加观察者、移除观察者和通知观察者等方法。创建具体的主题类ConcreteSubject该类维护了一个观察者列表并在状态改变时遍历通知所有注册的观察者。创建具体的观察者类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 ListObserver 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;Overridepublic 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 实现更新方法在收到主题通知时执行相应操作。
使用自定义接口实现方式的问题
主题与具体观察者之间存在紧耦合关系。观察者可能无法感知到其他已注册的新类型或特定类型。
尽管存在以上问题使用自定义接口实现方式是观察者模式的经典实现方式并且具有简单、直观的特点。
使用Java内置Observable类和Observer接口
主题继承Observable类并调用其方法进行状态改变通知观察者实现Observer接口并注册到主题上。
实现原理
创建一个具体主题类ConcreteSubject该类继承自Observable类。在具体主题类中定义状态改变方法并在该方法中调用setChanged()和notifyObservers()方法来通知所有注册的观察者。创建一个具体观察者类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;Overridepublic 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内置Observable和Observer实现方式存在以下问题
Observable是一个类而不是接口因此无法继承其他父类。Observable被标记为已过时虽然仍可使用但不推荐使用。观察者只能通过实现Observer接口来实现与主题的交互。
尽管存在以上问题使用Java内置Observable和Observer实现方式可以更方便地利用已有工具来快速实现观察者模式。
使用事件机制
通过定义事件类、监听器接口以及注册监听器等方式来实现观察者模式。当事件发生时主题发布该事件给已注册的监听器。
实现原理
定义一个事件类Event该类包含了需要传递给观察者的数据。创建一个主题类Subject其中包括注册观察者、移除观察者和触发事件等方法。创建一个具体主题类ConcreteSubject该类继承自主题类在具体主题中定义了相应的业务逻辑并在合适的时机通过调用触发事件方法来通知所有注册的观察者。创建一个接口或抽象类作为基础定义了处理特定类型事件的方法然后创建具体的处理器类实现这些方法以执行相应操作。观察者根据所需监听的特定类型事件来实现对应接口或抽象类并在其方法内进行相应操作。
实现代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;// 事件类
class Event {private String eventType;private MapString, 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 MapString, ListObserver observersMap new HashMap();Overridepublic void registerObserver(Observer observer, String eventType) {ListObserver observers observersMap.getOrDefault(eventType, new ArrayList());observers.add(observer);observersMap.put(eventType, observers);}Overridepublic void removeObserver(Observer observer, String eventType) {if (observersMap.containsKey(eventType)) {ListObserver 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来实现对不同类型事件的监听和相应操作。
在使用示例中我们创建了一个具体主题对象和两个具体观察者对象并将观察者注册到主题上。当主题触发特定类型事件时会自动通知对应的处理器进行相应操作。
使用事件机制实现方式可以更加灵活地处理不同类型的事件并使得代码结构更清晰。