观察者模式

介绍

观察者模式是发布/订阅(pub/sub)模式,是一种推模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某个主题对象。主题对象一旦发生改变时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式也解除了代码的耦合,让耦合的双方都依赖于抽象,而不是直接依赖于具体,从而让各自的变化不会影响另一边的变化。

结构图

来源于大话设计模式
Subject类 : 主题对象/抽象通知者,一般用一个接口或者抽象类实现,它把所有的观察者保存到一个集合里,每个主题都可以有任何的数量的观察者。该类为具体通知者定义了一些接口,比如添加、删除观察者和通知观察者事件等
Observer:为抽象观察者定义一个更新接口,在得到主题通知时更新自己
ConcreteSubject:具体主题,是抽象主题的扩展和具体实现。当发生改变时主动通知观察者
ConcreteObserver:具体观察者,是对抽象观察者的扩展和具体实现。当接收到主题通知时更新自己

使用场景

(1)一对多的情况下:一个对象发生改变同时需要改变其它对象
(2) 解除耦合:让耦合的双方都依赖于抽象,而不是依赖于具体。使得各自发生变化都不会影响对方
Spring的监听机制使用了观察者模式

举例实践

举例描述

在一个家庭中有男主人和女主人,还有两条狗子。当男主人或者女主人敲碗的时候,两只狗子听到敲碗就立即摇着尾巴跑过来吃饭。在这个事件中男主人和女主人就是主题通知者,狗子就是观察者,而敲碗就是通知狗狗来吃饭。

图解

在这里插入图片描述

主题抽象类owner

public interface Owner {

    /**
     * 添加宠物
     */
    void addPet(Pet pet);

    /**
     * 移除宠物
     */
    void removePet(Pet pet);
    /**
     * 通知狗狗们过来吃饭
     */
    void notifyEat();
}

主题具体类-host

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 男主人
 */
public class Host implements Owner{
    private static final List<Pet> petList = new CopyOnWriteArrayList<>();


    @Override
    public void addPet(Pet pet) {
        petList.add(pet);
    }

    @Override
    public void removePet(Pet pet) {
        petList.remove(pet);
    }

    @Override
    public void notifyEat() {
        for (Pet pet : petList) {
            pet.eat();
        }
    }
}

主题具体类-hostess


/**
 *女主人
 */
public class Hostess implements Owner{
    private static final List<Pet> petList = new CopyOnWriteArrayList<>();


    @Override
    public void addPet(Pet pet) {
        petList.add(pet);
    }

    @Override
    public void removePet(Pet pet) {
        petList.remove(pet);
    }

    @Override
    public void notifyEat() {
        for (Pet pet : petList) {
            pet.eat();
        }
    }
}

观察者抽象类-pet

@FunctionalInterface
public interface Pet {
    /**
     * 吃饭
     */
    void eat();
}

观察者具体类-dog1

public class Dog1 implements Pet{
    @Override
    public void eat() {
        System.out.println("dog1摇着尾巴来吃饭了...");
    }
}

观察者具体类-dog2

public class Dog2 implements Pet{
    @Override
    public void eat() {
        System.out.println("dog2摇着尾巴来吃饭了...");
    }
}

测试类

public class OTest {

    @Test
    public void test() {
        //创建通知者
        Owner host = new Host();
        Owner hostess = new Hostess();
        //创建观察者
        Pet dog1 = new Dog1();
        Pet dog2 = new Dog2();
        //将观察者注册到通知者中
        host.addPet(dog1);
        host.addPet(dog2);
        hostess.addPet(dog1);
        hostess.addPet(dog2);
        System.out.println("-------男主人早上敲碗--------");
        host.notifyEat();
        System.out.println("-------女主人中午敲碗--------");
        hostess.notifyEat();
        System.out.println("--------下午女主人带着狗狗1除去遛弯了--------");
        host.removePet(dog1);
        System.out.println("--------下午男主人敲碗啦--------");
        host.notifyEat();
    }
}

测试结果

-------男主人早上敲碗--------
dog1摇着尾巴来吃饭了...
dog2摇着尾巴来吃饭了...
-------女主人中午敲碗--------
dog1摇着尾巴来吃饭了...
dog2摇着尾巴来吃饭了...
--------下午女主人带着狗狗1除去遛弯了--------
--------下午男主人敲碗啦--------
dog2摇着尾巴来吃饭了...

Process finished with exit code 0

参考

《大话设计模式》. 程杰著

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值