观察者模式的生动理解

观察者模式顾名思义,可以从名字本身看到最直接的一个身份,观察者,其次,有了观察者之后,考虑一下,观察者的本质就是去观察,观察谁呢?当然是被观察者。这听起来有些拗口。那就举几个列子,浅显易懂。

(1)上课时的学生和老师,学生观察老师授课的一举一动,老师将自身的知识传播个学生。  观察者:学生;被观察者:老师。

(2)对于近几年电商的流行,我想这个场景大家绝对见过,我注册了某个购物平台后,比如某宝,某东等等。平时时不时的会接收到一条短信,其内容大致是对于商品的描述以及优惠活动,可以让消费者知道我们平台有活动了,可以前来购买。这个时候,可以确定一下身份。 观察者:消费者  ;被观察者:某平台。


这里大家可能对第二个有点疑惑,消费者又没有像学生那样时刻关注老师的动向,这里消费者怎么会变成观察者呢?事实上,这里说道的观察并不是时时刻刻需要观察 被观察者,而是这2者间有一种约定,一旦有新的事情发生,被观察者会通知到观察者。还有一点,就是大家发现没?这里都是一对多的关系,一个老师对多个学生,一个平台对多个消费者。


就如图:





下面我们对第二个例子进行代码的实践


观察者抽象类

package com.pyj.myapplication.Subject;

/**
 * 观察者抽象类
 *
 * @FileName: com.pyj.myapplication.Subject.Observer.java
 * @date: 2017-08-01 11:49
 */
public abstract class Observer {
    protected Subject subject;

    public Observer(Subject subject) {
        this.subject = subject;
        regisiter();
    }

    //参数为Object ,便于扩展
    abstract void update(Object obj);

    //注册
    void regisiter() {
        if (subject != null) {
            subject.addObserver(this);
            System.out.println(getClass() + "注册");
        }
    }

    //移除
    void remove() {
        if (subject != null) {
            subject.removeObserver(this);
            System.out.println(getClass() + "移除");

        }
    }

}

消费者1

package com.pyj.myapplication.Subject;

/**
 * 消费者1
 *
 * @author: 流冥
 * @date: 2017-08-01 12:03
 */
public class Customer1 extends Observer {

    public Customer1(Subject subject) {
        super(subject);
    }

    @Override
    void update(Object obj) {
        if (obj instanceof String) {
            System.out.println(getClass()+"接收到内容:  "+(String)obj);

        } else if (obj instanceof Integer) {
            System.out.println(getClass()+"接收到内容:  "+((int)obj));

        }

    }
}
消费者2

package com.pyj.myapplication.Subject;

/**
 * 消费者2
 *
 * @author: 流冥
 * @date: 2017-08-01 12:03
 */
public class Customer2 extends Observer {
    public Customer2(Subject subject) {
        super(subject);
    }

    @Override
    void update(Object obj) {
        if (obj instanceof String) {
            System.out.println(getClass()+"接收到内容:  "+(String)obj);

        } else if (obj instanceof Integer) {
            System.out.println(getClass()+"接收到内容:  "+((int)obj));

        }
    }
}

消费者3

package com.pyj.myapplication.Subject;

/**
 * 消费者3
 *
 * @author: 流冥
 * @date: 2017-08-01 12:03
 */
public class Customer3 extends Observer {
    public Customer3(Subject subject) {
        super(subject);
    }

    @Override
    void update(Object obj) {
        if (obj instanceof String) {
            System.out.println(getClass() + "接收到内容:  " + (String) obj);

        } else if (obj instanceof Integer) {
            System.out.println(getClass() + "接收到内容:  " + ((int) obj));

        }
    }
}

被观察者类:Subject

package com.pyj.myapplication.Subject;

import java.util.ArrayList;
import java.util.List;

/**
 * 被观察者
 *
 * @author: 流冥
 * @date: 2017-08-01 11:56
 */
public class Subject {

    List<Observer> list = new ArrayList<>();

    //注册观察者
    public void addObserver(Observer o) {
        list.add(o);
    }

    //移除观察者
    public void removeObserver(Observer o) {
        list.remove(o);
    }

    //通知观察者信息
    public void notiyAllObserver(Object o) {
        for (Observer observer : list) {
            observer.update(o);
        }
    }
}

 接下来开始进行试验:

public class Test {
    public static void main(String[] args){
        //定义被观察者
        Subject subject = new Subject();

        //定义观察者并注册
        Customer1 customer1 = new Customer1(subject);
        Customer2 customer2 = new Customer2(subject);
        Customer3 customer3 = new Customer3(subject);


    }
}
首先进行创建和关系绑定,我们看下打印日志:


通过日志,我们可以看到观察者和被观察者已经绑定成功。

接下来进行被观察者的通知:

public class Test {
    public static void main(String[] args){
        //定义被观察者
        Subject subject = new Subject();

        //定义观察者并注册
        Customer1 customer1 = new Customer1(subject);
        Customer2 customer2 = new Customer2(subject);
        Customer3 customer3 = new Customer3(subject);

        subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
        System.out.println("------------------------------------");
        subject.notiyAllObserver(123456);

    }
}
继续打印日志:


结果如上图,被观察者即消费者收到2条信息。这里要注意,我在代码中写到的这个方法

 //参数为Object ,便于扩展
    abstract void update(Object obj);
我的参数是Object类型的,这是便于扩展的一种写法,如果写死是String或者int的话,之后场景如果用到自定义的bean类的话进行通知,就会报错了。

接下来我们在进行解绑:

public class Test {
    public static void main(String[] args){
        //定义被观察者
        Subject subject = new Subject();

        //定义观察者并注册
        Customer1 customer1 = new Customer1(subject);
        Customer2 customer2 = new Customer2(subject);
        Customer3 customer3 = new Customer3(subject);

        subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
        System.out.println("---------------------------------------------------------");
        subject.notiyAllObserver(123456);

        //解绑注册
        customer1.remove();

        subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
        System.out.println("---------------------------------------------------------");
        subject.notiyAllObserver(123456);

    }
}

此处我们对Customer1进行了解绑 ,我们看下日志如何:


大家看到了吧 ,解绑了后,观察者继续发通知,Customer1就接收不到通知了。


到这里我讲的也到了尾声,对于举的列子我觉得还是比较容易理解的。若有读者看不懂或者我有写的不对的地方,也可以留言给我哦!





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值