优点
1.观察者和被观察者直接是抽象耦合的
缺点
- 如果一个被观察者有很多观察者的话,通知所有的观察者需要一定时间 【这种情况可以使用异步实现】
- 观察者和被观察者之间如果有循环依赖的话,有可能会陷入死循环中
- 观察者虽然能随时观察到被观察者的变化,但是紧紧是能知道被观察者变化了,却不知道被观察者是怎么改变的
模式结构
- 抽象被观察者:接口,用来规定具体被观察者需要实现的方法,比如添加、删除、通知观察者刷新
- 抽象观察者:接口,规定了具体观察者用来更新数据的方法
- 具体被观察者:具体的被观察者,当内部发生改变时候,通知所有已经添加的观察者
- 具体观察者:观察具体的被观察者,等接收到改变通知时候做出对应的操作
使用场景
1.某个对象更新了,其他对象也需要同步更新时候
2.当对象更新时候仅需要通知别人改变了,不需要告诉其他对象是怎么改变的
步骤1
创建抽象被观察者
/**
* 被观察者
* @author shen
*
*/
public interface Observerable {
/**
* 添加观察者
* @param observer
*/
public void add(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void remove(Observer observer);
/**
* 更新消息
*/
public void notifyItem();
}
步骤2
创建抽象观察者
/**
* 观察者
* @author shen
*
*/
public interface Observer {
public void message();
}
步骤3
实现被观察者接口(具体被观察者),用一个List添加、删除观察者,当被观察者发生变动时候调用notifyItem方法循环通知所添加的观察者
import java.util.ArrayList;
import java.util.List;
public class MyServer implements Observerable {
private List<Observer> mList;
public MyServer() {
mList = new ArrayList<Observer>();
}
@Override
public void add(Observer observer) {
// TODO Auto-generated method stub
mList.add(observer);
}
@Override
public void remove(Observer observer) {
// TODO Auto-generated method stub
if (!mList.isEmpty()) {
mList.remove(observer);
}
}
@Override
public void notifyItem() {
// TODO Auto-generated method stub
for (Observer ob : mList) {
ob.message();
}
}
}
步骤4
定义具体观察者
public class User implements Observer {
private String name;
public User(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println(name + "接受到消息");
}
}
步骤5
创建了3个具体观察者,使用MyServer添加注册成为观察者,当行为有发生改变时候调用notifyItem()进行轮询通知观察者
public class Main {
public static void main(String[] args) {
Observer zhang = new User("张三");
Observer li = new User("李四");
Observer wang = new User("王五");
MyServer server = new MyServer();
server.add(zhang);
server.add(li);
server.add(wang);
server.notifyItem();
}
}
运行效果
图片.png