返回 登录
0

最常用的设计模式

我的博文地址
最近在学习观察者模式,下面我想给分享自己对观察者模式的理解和心得,观察者模式是我们使用频率最高的设计模式之一,用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将做出反应。在观察这模式中发生改变的就是观察目标,而被通知的对象视为观察目标,而被通知的对象视为观察者,一个观察目标可以对应多个观察者。而且这些观察者之间可以没有任何相互的联系,可以根据需要增加或删除观察者,使系统更易拓展。可以说观察者在我们生活中的实例无处不在,比如我们常用的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 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();      
    }
}
评论