最近在学习观察者模式,下面我想给分享自己对观察者模式的理解和心得,观察者模式是我们使用频率最高的设计模式之一,用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将做出反应。在观察这模式中发生改变的就是观察目标,而被通知的对象视为观察目标,而被通知的对象视为观察者,一个观察目标可以对应多个观察者。而且这些观察者之间可以没有任何相互的联系,可以根据需要增加或删除观察者,使系统更易拓展。可以说观察者在我们生活中的实例无处不在,比如我们常用的QQ空间就可以理解为一种观察者模式,比如当我们CSDN发一篇博客的时候,首先管理员会看见,他们会对我们这篇博客进行审核,另外广大的网友也可看见,他们可以点赞亦可评论,甚至还能举报,在这里我们发的博客作为目标,而管理员和网友作为观察者,他们可以对这篇博客有反应,这就是观察者模式。
观察者模式是对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式一般有四个角色,第一个是目标(Subject),目标又称主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者观察,它提供一系列的方法来增加和删除观察者对象,同时定义了通知方法。第二个是具体目标(ConcreteSubject),具体目标是目标类的子类,通常包含有经常发生改变的数据当它的状态发生改变时,向其各个观察者发出通知。第三个是观察者(observe),观察者将对观察目标的改变做出反应,观察者一般定义为一个接口,该接口声明了更新数据的方法,通常称为抽象观察者。最后一个是具体观察者(ConcreteObserve),比如我们在上文中说的CSDN的管理员和网友,所以你们在看到这篇博文的时候就是一个具体的观察者,在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关的状态,这些状态需要和具体目标的状态保持一致。下面我们围着这四个角色给出一个具体的例子,加深一下理解。我们在看汤姆和杰瑞动画的时候,虽然汤姆永远不能吃到杰瑞,但是汤姆叫三声还是会让杰瑞抖一抖的,而其他动物会有什么反应呢?下面我们以汤姆猫的叫声为具体的目标,杰瑞其他动物作为观察者看看他们会有什么反应。
我们先定义抽象的目标类,代码如下:
public abstract class MySubject
{
protected ArrayList observers = new ArrayList();
//注册方法
public void attach(MyObserver observer)
{
observers.add(observer);
}
//注销方法
public void detach(MyObserver observer)
{
observers.remove(observer);
}
public abstract void cry(); //抽象通知方法
}
然后我们写一个目标类的子类,也就是具体的目标类,就是我们前面说的汤姆猫的叫声
public class Cat extends MySubject
{
public void cry()
{
System.out.println("猫叫!");
System.out.println("----------------------------");
for(Object obs:observers)
{
((MyObserver)obs).response();
}
}
}
汤姆叫了一声之后,它的观察者会有什么反应呢,虽然个动物的反应不尽相同,但是他们都会做出反应,因此我们可以将观察到汤姆猫叫声的动物抽象成一个观察者接口
public interface MyObserver
{
void response(); //抽象响应方法
}
下面就是其他动物具体的反应了,来我们看看,他们有什么反应呢,我们先来看看小老鼠的
public class Mouse implements MyObserver
{
public void response()
{
System.out.println("老鼠努力逃跑!");
}
}
小狗
public class Dog implements MyObserver
{
public void response()
{
System.out.println("狗跟着叫!");
}
}
猪
public class Pig implements MyObserver
{
public void response()
{
System.out.println("猪没有反应!");
}
}
写好以上类之后,我们用主方法调用,看看小动物对汤姆猫的叫声具体有什么反应呢?
public class Client
{
public static void main(String a[])
{
MySubject subject=new Cat();
MyObserver obs1,obs2,obs3;
obs1=new Mouse();
obs2=new Mouse();
obs3=new Dog();
subject.attach(obs1);
subject.attach(obs2);
subject.attach(obs3);
MyObserver obs4;
obs4=new Pig();
subject.attach(obs4);
subject.cry();
}
}