观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主题是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。 [1]
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
这个是百度百科的解释,通俗来说就是:
就好像你关注了一个店家,然后这个店家发的消息,只要一发新商品,你这边就能马上收到,然后这个店家可以被多人关注的,而且店家也有权利选择关注的人,可以进行添加新的关注人也可以移除关注的人,额,大概就是这个意思,观察者模式是一对多的,不像那个接口回调是一对一的
所以它的定义跟特点就是:
定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
观察者模式是一种对象行为型模式,其主要优点如下。
- 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
- 目标与观察者之间建立了一套触发机制。
它的主要缺点如下。
- 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
- 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
怎么去实现
实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。
1. 模式的结构
观察者模式的主要角色如下。
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
观察者模式的结构图如图 1 所示。
代码的实现:
先整个关注的人出来,咱店家发布的那些东西毕竟是给这些人看
/**
* 抽象观察者
* @author Administrator
*
*/
public interface Observer {
void response();//具体反应
}
/**
* 具体观察者1
* @author Administrator
*
*/
public class ConcreteObserver1 implements Observer{
@Override
public void response() {
// TODO Auto-generated method stub
System.out.println("观察者1觉得这个有点吊,并且做出反应");
}
}
/**
* 具体观察者2
* @author Administrator
*
*/
public class ConcreteObserver2 implements Observer{
@Override
public void response() {
// TODO Auto-generated method stub
System.out.println("观察者2觉得这个有点垃圾,并且做出反应");
}
}
然后设置主题
import java.util.ArrayList;
import java.util.List;
/**
* 抽象主题
*
* @author Administrator
*
*/
public abstract class Subject {
protected List<Observer> observers = new ArrayList<Observer>();
// 增加观察者方法
public void add(Observer observer) {
observers.add(observer);
}
// 删除观察者方法
public void remove(Observer observer) {
observers.remove(observer);
}
public abstract void notifyObserver(); // 通知观察者方法
}
/**
* 具体主题
* @author Administrator
*
*/
public class ConcreteSubject extends Subject{
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
System.out.println("发布了一件新商品");
for(Object obs:observers) {
((Observer)obs).response();
}
}
}
然后设计个场景,商家发布了个主题,然后通知关注的人
public static void main(String[] args) {
// TODO Auto-generated method stub
Subject subject=new ConcreteSubject();
Observer obs1=new ConcreteObserver1();
Observer obs2=new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
输出的是这个:
发布了一件新商品
观察者1觉得这个有点吊,并且做出反应
观察者2觉得这个有点垃圾,并且做出反应
然后应用场景其实也挺广泛的,就主要是那种一对多的,而且是一个属性的改变得要通知到其他人,就会影响其他相应物体做出改变的那种,额,具体就不举例子了