- 定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。即:
- 监视和被监视 模式
- 订阅发布模式
监视模式:
package com.example.spring.design.Observer;
import java.util.ArrayList;
/**
* @Author: hyh
* @Date: 2021/12/8 9:46
* 抽象一个被监视者
**/
public abstract class Monitored {
// 监视人
private ArrayList<Monitor> monitors = new ArrayList<>();
// 添加监视人
public boolean register(Monitor m) {
this.monitors.add(m);
return true;
}
// 删除监视人
public boolean remove(Monitor m) {
boolean contains = this.monitors.contains(m);
if (contains) {
this.monitors.remove(m);
return true;
}
return false;
}
//通知
public void notifying(String s) {
for (Monitor m: monitors) {
m.notifying(s);
}
}
}
// 监视女朋友
class Girl extends Monitored{
public void eat(){
super.notifying("女朋友开始吃饭了");
}
}
/**
* @Author hyh
* @Date 9:48 2021/12/8
* 抽象一个监视者
**/
abstract class Monitor {
abstract void notifying(String s);
}
// 1号男朋友
class Boy1 extends Monitor{
@Override
void notifying(String s) {
System.out.println(s);
}
}
// 2号男朋友
class Boy2 extends Monitor{
@Override
void notifying(String s) {
System.out.println(s);
}
}
class Tset{
public static void main(String[] args) {
Girl girl = new Girl();
Boy1 boy1 = new Boy1();
//Boy2 boy2 = new Boy2();
//添加监视人1
girl.register(boy1);
girl.eat();
}
}
输出:
女朋友开始吃饭了
订阅发布:
package com.example.spring.design.Observer;
import java.util.ArrayList;
/**
* @Author: hyh
* @Date: 2021/12/8 14:01
* 定义主题接口
**/
public interface Subject {
// 订阅
void register(Observer m);
// 取消
void remove(Observer m);
//通知
void notifying(Subject s);
void display();
}
class AV implements Subject {
private String name;
private String url;
// 监视人
private ArrayList<Observer> obs = new ArrayList<>();
@Override
public void register(Observer m) {
this.obs.add(m);
}
@Override
public void remove(Observer m) {
boolean contains = this.obs.contains(m);
if (contains) {
this.obs.remove(m);
}
}
// 更新资源
public void update(String name, String url) {
this.name = name;
this.url = url;
this.notifying(this);
}
@Override
public void notifying(Subject s) {
for (Observer ob : obs) {
ob.update(s);
}
}
@Override
public void display() {
System.out.println(this.name);
System.out.println(this.url);
}
}
interface Observer {
void update(Subject o);
}
class Ds1 implements Observer {
@Override
public void update(Subject o) {
o.display();
}
}
class Test {
public static void main(String[] args) {
// AV 频道
AV av = new AV();
// 屌丝
Ds1 ds1 = new Ds1();
// 订阅
av.register(ds1);
av.update("苍老师视频", "地址:www.caolaoshi.com");
}
}
输出:
苍老师视频
地址:www.caolaoshi.com
java.util包提供一个接口 一个类 咱可以实现接口 继承类来实现观察者模式,但是有很多缺点:
package java.util;
public interface Observer {
void update(Observable o, Object arg);
}
package java.util;
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector<>();
}
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public synchronized void deleteObservers() {
obs.removeAllElements();
}
/**
* Marks this <tt>Observable</tt> object as having been changed; the
* <tt>hasChanged</tt> method will now return <tt>true</tt>.
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* Indicates that this object has no longer changed, or that it has
* already notified all of its observers of its most recent change,
* so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
* This method is called automatically by the
* <code>notifyObservers</code> methods.
*
* @see java.util.Observable#notifyObservers()
* @see java.util.Observable#notifyObservers(java.lang.Object)
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* Tests if this object has changed.
*
* @return <code>true</code> if and only if the <code>setChanged</code>
* method has been called more recently than the
* <code>clearChanged</code> method on this object;
* <code>false</code> otherwise.
* @see java.util.Observable#clearChanged()
* @see java.util.Observable#setChanged()
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this <tt>Observable</tt> object.
*
* @return the number of observers of this object.
*/
public synchronized int countObservers() {
return obs.size();
}
}
java.util.Observable的确点:
Observable是一个“类”而不是一个“接口”,更糟的是,它甚至没有实现一个接口。不幸的是,java.util.Observable的实现有许多问题,限制了它的使用和复用。这并不是说它没有提供有用的功能,我们1只是想提醒大家注意一些事实。
Observable是一个类
你已经从我们的原则中得知这不是一件好事,但是,这到底会造成什么问题呢?首先,因为Observablc是一个“类”,你必须设计一个类继承它。如果某类想同时具有Observable类和另一个超类的行为,就会陷入两难,毕竞Java不支持多重继承。这限制了Observable的复用潜力
再者,因为没有Observable接口,所以你无法建立自己的实现,和Java内置的Observer API搭配使用,也无法将java.util的实现换成另一套做法的实现
Observable将关键的方法保护起来
如果你看看Observable APl,你会发现setChanged()方法被保护起来了(被定义成protected)。那又怎么样呢?这意味着:除非你继承自Observable,否则你无法创建Observable实例并组合到你自己的对象中来。这个设计违反了第二个设计原则:“多用组合,少用继承”。