设计模式-观察者模式
原创
©著作权归作者所有:来自51CTO博客作者写代码的lorre的原创作品,请联系作者获取转载授权,否则将追究法律责任
定义
观察者模式它定义了一种一对多的依赖关系,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
假如一个对象的状态更新,需要其他对象也同步更新的时候,而且这些其他对象可以动态改变,这个时候我们的观测者模式就派上用场类。
应用场景
观察者模式常用于实现订阅功能的场景,比如说微博的订阅,消息订阅等。我们订阅了它们,它们在有更新的时候就会给我们推送它们的更新信息,这样我们就不用每次都要去刷新它的状态了
模式中的角色:
- 主题 I Subject 接口定义
- 主题类编写
- 观察者接口 I Observe 定义
- 观察者类实现
角色关系UML:
以下以订阅报纸为例子
报社出版报纸,每天更新报纸的内容,我们订阅了报纸,就会每天有人送报纸过来(当然你也可以自己去拿),从报社订报纸的人有很多,取消订阅的人也很多,因此订阅者是可以动态变化的
UML图如下:
java代码
主题接口
package demo12;
/**
*
* @ClassName: Subject
* @Description:主题接口
* @author cheng
* @date
public interface Subject
/**
*
* @Title: registerObserver
* @Description: 注册观察者
* @param
void registerObserver(Observer o);
/**
*
* @Title: removeObserver
* @Description:移除观察者
* @param
void removeObserver(Observer o);
/**
*
* @Title: notifyObserver
* @Description:通知观察者
*/
void notifyObserver();
/**
*
* @Title: setState
* @Description:修改状态
* @param
void
具体主题
package demo12;
import java.util.ArrayList;
import java.util.List;
/**
*
* @ClassName: Newspaper
* @Description:报社
* @author cheng
* @date
public class Newspaper implements Subject
//记录观察者列表
private List<Observer> list;
private String context;
public Newspaper() {
list = new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
if (list != null && list.size() != 0) {
for (Observer o : list) {
o.update(this.context);
}
}
}
@Override
public void registerObserver(Observer o) {
list.add(o);
System.out.println(o.getName() + "订阅了报纸");
}
@Override
public void removeObserver(Observer o) {
list.remove(o);
System.out.println(o.getName() + "取消了订阅");
}
@Override
public void setState(String context) {
System.out.println("报社出版了新的报纸,内容为:" + context);
this.context = context;
notifyObserver();
}
}
观察者接口
package demo12;
/**
*
* @ClassName: Observer
* @Description:观察者实现的接口
* @author cheng
* @date
public interface Observer
/**
*
* @Title: getName
* @Description: 获取观察者名称
* @return
String getName();
/**
*
* @Title: update
* @Description: 更新
* @param
void
具体观察者
package demo12;
/**
*
* @ClassName: Subscriber
* @Description:订阅者
* @author cheng
* @date
public class Subscriber implements Observer
private String name;
public Subscriber(String name) {
this.name = name;
}
/**
* 获取名称
*/
public String getName() {
return this.name;
}
/**
* 更新状态
*/
@Override
public void update(String context) {
System.out.println("订阅者:" + name + "收到了消息,内容为:"
测试
package demo12;
/**
*
* @ClassName: ClientTest
* @Description:测试
* @author cheng
* @date
public class ClientTest
public static void main(String[] args) {
Subject subject = new Newspaper();
Observer o1 = new Subscriber("张三");
Observer o2 = new Subscriber("李四");
Observer o3 = new Subscriber("王五");
subject.registerObserver(o1);//添加观察者
subject.registerObserver(o2);
subject.registerObserver(o3);
subject.setState("2017-8-15 今天的最新的报纸内容");//更新状态
subject.removeObserver(o1);//移除观察者
subject.setState("2017-8-16 今天的最新的报纸内容");
}
}
运行结果