观察者模式
观察者模式=发布-订阅模式
Android中常用的EventBus以及Google Guava包中的event bus等都是对观察者模式的实现。
个人理解,从广义上讲,消息队列也是一种观察者模式的实现。
观察者模式的本质就是触发联动:在修改目标对象的状态的时候,就会触发相应的通知,然后会循环调用所有观察者对象相应的方法。
下面,我们实现以下功能:
当有新员工入职时,为其开通公司内部系统账号,并为其制作工牌;
当有员工离职时,为其关闭公司内部系统账号,并收回其工牌;
示例1:使用JDK中已有的观察者模式实现
目标类
public class Employee extends Observable {
private String name;
private Status status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
//有员工变动,则手动设置目标变化
this.setChanged();
//说明有员工入职
if(status == Status.NEW){
this.notifyObservers(this);
}else if(status == Status.LEAVE){
this.notifyObservers(this);
}
}
enum Status{
NEW, LEAVE
}
}
观察者1
public class AccountObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
Employee employee = (Employee)o;
Employee.Status status = employee.getStatus();
if(status == Employee.Status.NEW){
System.out.println(String.format("create account for [employee : %s]", employee.getName()));
}else if(status == Employee.Status.LEAVE){
System.out.println(String.format("delete account for [employee : %s]", employee.getName()));
}
}
}
观察者2
public class WorkCardObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
Employee employee = (Employee)o;
Employee.Status status = employee.getStatus();
if(status == Employee.Status.NEW){
System.out.println(String.format("make an work card for [employee : %s]", employee.getName()));
}else if(status == Employee.Status.LEAVE\){
System.out.println(String.format("reclaim [employee : %s] work card", employee.getName()));
}
}
}
验证
public class Client {
public static void main(String[] args){
Employee employee = new Employee();
employee.setName("xiaoming");
employee.addObserver(new AccountObserver());
employee.addObserver(new WorkCardObserver());
employee.setStatus(Employee.Status.NEW);
System.out.println("1 year later...");
employee.setStatus(Employee.Status.LEAVE);
}
}
输出如下:
make an work card for [employee : xiaoming]
create account for [employee : xiaoming]
1 year later...
reclaim [employee : xiaoming] work card
delete account for [employee : xiaoming]
示例2:使用Google Guava中的event bus实现
目标
public class Employee {
private String name;
private Status status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
enum Status {
NEW, LEAVE
}
}
订阅者或观察者
public class EmployeeEventSubscriber {
@Subscribe
public void handleNew(Employee employee) {
System.out.println(String.format("create account for [employee : %s]", employee.getName()));
System.out.println(String.format("make an work card for [employee : %s]", employee.getName()));
}
@Subscribe
public void handleLeave(Employee employee) {
System.out.println(String.format("delete account for [employee : %s]", employee.getName()));
System.out.println(String.format("reclaim [employee : %s] work card", employee.getName()));
}
}
验证
public class Client {
public static void main(String[] args){
EventBus eventBus = new EventBus();
eventBus.register(new EmployeeEventSubscriber());
Employee employee = new Employee();
employee.setName("xiaoming");
employee.setStatus(Employee.Status.NEW);
eventBus.post(employee);
System.out.println("1 year later...");
employee.setStatus(Employee.Status.LEAVE);
eventBus.post(employee);
}
}
输出
delete account for [employee : xiaoming]
reclaim [employee : xiaoming] work card
create account for [employee : xiaoming]
make an work card for [employee : xiaoming]
1 year later...
delete account for [employee : xiaoming]
reclaim [employee : xiaoming] work card
create account for [employee : xiaoming]
make an work card for [employee : xiaoming]
guava的优势:①不必实现接口;②处理事件或状态变化的方法命名没有约束,而JDK中只能是update
对guava中event bus的源码简单分析,点击这里。
参考
《研磨设计模式--第12章 观察者模式》
菜鸟教程:观察者模式
Last updated