1 定义
定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
2 实例
如上图所示,服务号就是我们的主题,使用者就是观察者。现在我们明确下功能:
1、服务号就是主题,业务就是推送消息
2、观察者只需要订阅主题,只要有新的消息就会送来
3、当不想要此主题消息时,取消订阅
4、只要服务号还在,就会一直有人订阅
3 类图
4 代码实现
模拟一个微信3D彩票服务号,和一些订阅者。
两种实现方式:1.自我实现一个观察者模式 2.基于JDK实现观察者模式
(1)自己实现观察者
1 主题接口
package com.grm.pattern.observer;
import java.util.Observer;
/**
* 主题接口,所有的主题必须实现此接口
*
* @author gaorimao
* @since 2022-01-30
*/
public interface Subject {
/**
* 注册一个观察着
*
* @param observer 观察者
*/
void registerObserver(Observer observer);
/**
* 移除一个观察者
*
* @param observer 观察者
*/
void removeObserver(Observer observer);
/**
* 通知所有的观察者
*/
void notifyObservers();
}
2 观察者接口
package com.grm.pattern.observer;
/**
* 观察者接口,所有的观察者必须实现此接口
*
* @author gaorimao
* @since 2022-01-30
*/
public interface Observer {
/**
* 主题改变时调用
*
* @param msg msg
*/
void update(String msg);
}
3 主题实现类
package com.grm.pattern.observer.impl;
import com.grm.pattern.observer.Observer;
import com.grm.pattern.observer.Subject;
import java.util.ArrayList;
import java.util.List;
/**
* 主题实现类
*
* @author gaorimao
* @since 2022-01-30
*/
public class SubjectImpl implements Subject {
/**
* 定义一堆观察者
*/
private List<Observer> observers = new ArrayList<>();
/**
* 主题推送的消息
*/
private String msg;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int index = observers.indexOf(observer);
if (index >= 0) {
observers.remove(index);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(msg);
}
}
/**
* 主题更新消息
*
* @param msg 更新的消息
*/
public void setMsg(String msg) {
this.msg = msg;
// 通知给观察者
notifyObservers();
}
}
4 观察者实现类
观察者1
package com.grm.pattern.observer.impl;
import com.grm.pattern.observer.Observer;
import com.grm.pattern.observer.Subject;
/**
* 观察者1
*
* @author gaorimao
* @since 2022-01-30
*/
public class Observer1 implements Observer {
/**
* 订阅主题
*
* @param subject 主题
*/
public Observer1(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String msg) {
System.out.println("observer1 得到 3D 号码 -->" + msg);
}
}
观察者2
package com.grm.pattern.observer.impl;
import com.grm.pattern.observer.Observer;
import com.grm.pattern.observer.Subject;
/**
* 观察者2
*
* @author gaorimao
* @since 2022-01-30
*/
public class Observer2 implements Observer {
/**
* 订阅主题
*
* @param subject 主题
*/
public Observer2(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String msg) {
System.out.println("observer2 得到 3D 号码 -->" + msg);
}
}
3 Test测试类
package com.grm.pattern.observer;
import com.grm.pattern.observer.impl.Observer1;
import com.grm.pattern.observer.impl.Observer2;
import com.grm.pattern.observer.impl.SubjectImpl;
public class Test {
public static void main(String[] args) {
//模拟一个3D的服务号
SubjectImpl SubjectImpl = new SubjectImpl();
//客户1
Observer observer1 = new Observer1(SubjectImpl);
Observer observer2 = new Observer2(SubjectImpl);
SubjectImpl.setMsg("127");
SubjectImpl.setMsg("333");
SubjectImpl.setMsg("666");
}
}
4 测试结果
(2)基于jdk实现观察者模式
1 主题1
package com.grm.pattern.observer.jdk;
import java.util.Observable;
/**
* 主题1
*
* @author gaorimao
* @since 2022-01-30
*/
public class SubjectImpl1 extends Observable {
private String msg;
public String getMsg() {
return msg;
}
/**
* 主题更新消息
*
* @param msg
*/
public void setMsg(String msg) {
this.msg = msg;
setChanged();
notifyObservers();
}
}
2 主题2
package com.grm.pattern.observer.jdk;
import java.util.Observable;
/**
* 主题2
*
* @author gaorimao
* @since 2022-01-30
*/
public class SubjectImpl2 extends Observable {
private String msg;
public String getMsg() {
return msg;
}
/**
* 主题更新消息
*
* @param msg
*/
public void setMsg(String msg) {
this.msg = msg;
setChanged();
notifyObservers();
}
}
3 观察者
package com.grm.pattern.observer.jdk;
import java.util.Observable;
import java.util.Observer;
/**
* 观察者
*
* @author gaorimao
* @since 2022-01-30
*/
public class ObserverImpl implements Observer {
public void registerSubject(Observable observable) {
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof SubjectImpl1) {
SubjectImpl1 subject1 = (SubjectImpl1) o;
System.out.println("这是主题1发送的消息 -- >" + subject1.getMsg());
}
if (o instanceof SubjectImpl2) {
SubjectImpl2 subject2 = (SubjectImpl2) o;
System.out.println("这是主题2发送的消息 -- >" + subject2.getMsg());
}
}
}
4 测试类
package com.grm.pattern.observer.jdk;
import com.grm.pattern.observer.myself.impl.Observer1;
public class Test {
public static void main(String[] args) {
SubjectImpl1 subject1 = new SubjectImpl1();
SubjectImpl2 subject2 = new SubjectImpl2();
ObserverImpl observer = new ObserverImpl();
observer.registerSubject(subject1);
observer.registerSubject(subject2);
subject1.setMsg("11111111");
subject2.setMsg("22222222");
}
}
5 测试结果
至此,观察者模式演示结束!