1.观察者模式又称为订阅者模式
1)观察者模式中有如下几个角色:
抽象观察者 Observer
具体观察者 ObserverA,ObServerB
抽象主题 Subject
具体主题 SubjectA
2)观察者模式又分为推方式和拉方式:
推方式:主题对象推送主题的详细信息,不管观察者是否需要。
拉方式:主题对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于观察者到主题对象中拉数据。一般这种模型中,会将主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用方式获取了。
说明:推方式,推送的主题的详细信息,拉方式,推送的是具体主题对象。
3)Java标准支持的观察者模式
在Java中,提供了一个Obseverable类以及一个Observer接口,构成了Java语言对观察者模式的支持。
Observer接口只定义了一个update()方法,当被观察者对象的状态发生改变时,被观察者对象的notiryObservers()方法就会调用这个方法。
Observer类是被观察者的基类。
2.示例演示
1)推方式示例代码:
interface Observer{ //抽象观察者
public void update(String state);
}
//具体观察者A
class ObserverA implements Observer{
private String myState;
public void update(String state){
myState = state;
}
public String getState(){
return myState;
}
}
//具体观察者B
class ObserverB implements Observer{
private String myState;
public void update(String state){
myState = state;
}
public String getState(){
return myState;
}
}
abstract class Subject{
List<Observer> list = new ArrayList<>();
public void register(Observer observer){ //观察者注册
list.add(observer);
}
public void remove(Observer observer){ //观察者删除
list.remove(observer);
}
public void notifyAllObserver(String state){ //更新所有观察者的状态
for(Observer observer:list){
observer.update(state);
}
}
}
class SubjectA extends Subject{
private String changeState;
public void setMessage(String changeMessage){
this.changeState = changeMessage;
this.notifyAllObserver(changeMessage);
}
public String getState(){
return changeState;
}
}
class Test{
public static void main(String[] args) {
ObserverA obvA = new ObserverA(); //创建观察者A
ObserverB obvB = new ObserverB(); //创建观察者B
SubjectA sub = new SubjectA();
sub.register(obvA);
sub.register(obvB);
sub.setMessage("状态一");
System.out.println(obvA.getState());;
System.out.println(obvB.getState());;
System.out.println("---------------");
sub.setMessage("改变状态");
System.out.println(sub.getState());
System.out.println(obvA.getState());;
System.out.println(obvB.getState());;
}
}
2)拉方式示例代码://抽象观察者
interface Observer{
public void update(Subject sub);
}
//具体观察者
class ObserverA implements Observer{
String state;
public void update(Subject sub){ //相比与推方式,这里参数是具体主题,观察者可以根据需要获取需要信息
this.state = ((SubjectA)sub).myState;
}
public String getState(){
return state;
}
}
class ObserverB implements Observer{
String state;
public void update(Subject sub){
this.state = ((SubjectA)sub).myState;
}
public String getState(){
return state;
}
}
//抽象主题
abstract class Subject{
List<Observer> list = new ArrayList<>();
public void register(Observer observer){ //注册观察者
list.add(observer);
}
public void remove(Observer observer){ //删除观察者
list.remove(observer);
}
public void notifyAllObserver(){
for(Observer observer:list){
observer.update(this); //更新观察者
}
}
}
//具体主题
class SubjectA extends Subject{
String myState;
public void setState(String myState){
this.myState = myState;
this.notifyAllObserver();
}
public String getState(){
return myState;
}
}
class Test{
public static void main(String[] args) {
ObserverA observerA = new ObserverA();
ObserverB observerB = new ObserverB();
SubjectA sub = new SubjectA();
sub.register(observerA); //注册
sub.register(observerB); //注册
sub.setState("状态一");
System.out.println(observerA.getState());
System.out.println(observerB.getState());
System.out.println("---------推送-----------");
sub.setState("改变状态一");
System.out.println(observerA.getState());
System.out.println(observerB.getState());
}
}
说明:notifyAllObserver()函数在推方式中是只能放在具体主题中,而在拉方式中方抽象主题中和具体主题中都是可以的。
3)使用观察者库
库中已经有了抽象观察者接口Oberver和抽象主题类Observable,我们直接使用就行了。
class ObserverA implements Observer{
String state;
@Override
public void update(Observable o, Object arg) {
this.state = ((SubjectA)o).getState(); //显然库中也是使用的拉方式
}
public String getState(){
return state;
}
}
class ObserverB implements Observer{
String state;
@Override
public void update(Observable o, Object arg) {
this.state = ((SubjectA)o).getState();
}
public String getState(){
return state;
}
}
class SubjectA extends Observable{ //这里的Observer相当于上面写的类Subject
private String myState;
public void setState(String state){
this.myState = state;
this.setChanged();
this.notifyObservers(); //相当于上面写的notiyfyAllObserver();
}
public String getState(){
return myState;
}
}
class Test{
public static void main(String[] args) {
ObserverA obA = new ObserverA();
ObserverB obB = new ObserverB();
SubjectA sub = new SubjectA();
sub.addObserver(obA);
sub.addObserver(obB);
sub.setState("状态一");
System.out.println(obA.getState());
System.out.println(obB.getState());
System.out.println("-------改变状态-------");
sub.setState("改变状态一");
System.out.println(obA.getState());
System.out.println(obB.getState());
}
}
参考:
https://blog.youkuaiyun.com/itachi85/article/details/50773358
https://blog.youkuaiyun.com/yanbober/article/details/45484749