设计模式 | 观察者模式

简介: 设计模式 | 观察者模式

说明

这个设计模式很常用、重要, 所以要好好看。这是一个非常经典的设计模式, 解决了不少问题, 在实际项目中应用比较广泛。

先简单说一下设计模式的定义: 一旦主体对象状态发生改变,与之关联的观察者对象会收到通知,并进行相应操作。观察者模式实现了低耦合,非侵入式的通知与更新机制。

举个🌰, 大家都知道, 今年的猪肉价格让人有望而却步, 让原本就不富裕的家庭更是雪上加霜, 我有个想法就是, 让这个超市猪肉价格一降价就通知我, 好让我能及时以较低价格购买。 我这个时候我就需要观察者, 来观察猪肉的价格, 然后及时通知我。

示例

<?php
/**
 * Created by 憧憬.
 */
/**
 * 观察者约束
 * Interface Observer
 */
interface Observer {
    // 到时候接受到通知及时作出反应
    public function update();
}
/**
 * 被观察者 到时候也好通知观察者
 * Interface Observable
 */
interface Observable {
    // 添加观察者
    public function addObserver(Observer $observer);
    // 删除观察者
    public function deleteObserver(Observer $observer);
    // 通知观察者
    public function notifyObserver();
}
//
///**
// * 猪肉
// * Class Pork
// */
//class Pork implements Observable {
//
//    public $observableList;
//
//    public $price;
//
//    public function addObserver(Observer $observer)
//    {
//        $this->observableList[] = $observer;
//    }
//
//    public function deleteObserver(Observer $observer)
//    {
//        foreach ($this->observableList as $k => $v) {
//            if ($v === $observer) {
//                unset($this->observableList[$k]);
//            }
//        }
//    }
//
//    public function notifyObserver()
//    {
//        foreach ($this->observableList as $observer) {
//            $observer->update();
//        }
//    }
//
//    /**
//     * 设置猪肉价格
//     * @param $price
//     * @author: 憧憬
//     */
//    public function setPrice($price)
//    {
//        $this->price = $price;
//        $this->notifyObserver();
//    }
//
//}
//
/**
 * 博主自己
 * Class Aoppp
 */
class Aoppp implements Observer {
    public function update()
    {
        echo '憧憬 有你的通知来了  快快行动';
    }
}
/**
 * 李四也想吃猪肉
 * Class Lisi
 */
class Lisi implements Observer {
    public function update()
    {
        echo '李四 有你的通知来了  快快行动';
    }
}
//$pork = new Pork();
//
//$pork->addObserver(new Aoppp());
//$pork->addObserver(new Lisi());
//$pork->setPrice(100);
/**
 * 这个时候你发现 可以随便通知任何人,  也可以移除观察者  但是每个想观察的对象都要写这个函数 有点重复
 * 我们可以抽离出来
 */
class ObserverUtil implements Observable {
    public $observableList;
    public function addObserver(Observer $observer)
    {
        $this->observableList[] = $observer;
    }
    public function deleteObserver(Observer $observer)
    {
        foreach ($this->observableList as $k => $v) {
            if ($v === $observer) {
                unset($this->observableList[$k]);
            }
        }
    }
    public function notifyObserver()
    {
        foreach ($this->observableList as $observer) {
            $observer->update();
        }
    }
}
/**
 * 将猪肉类改为继承
 * Class Pork
 */
class Pork extends ObserverUtil {
    public $price;
    /**
     * 设置猪肉价格
     * @param $price
     * @author: 憧憬
     */
    public function setPrice($price)
    {
        $this->price = $price;
        $this->notifyObserver();
    }
}
$pork = new Pork();
$pork->addObserver(new Aoppp());
$pork->addObserver(new Lisi());
$pork->setPrice(100);
// 这样的话 你要监听鸡肉 还是什么乱七八糟的 都要方便很多了

观察者模式在实际项目的应用中非常常见,比如你到 ATM 机器上取钱,多次输错密码,卡就会被 ATM 吞掉,吞卡动作发生的时候,会触发哪些事件呢?第一摄像头连续快拍,第二,通知监控系统,吞卡发生; 第三,初始化 ATM 机屏幕,返回最初状态,你不能因为就吞了一张卡,整个 ATM 都不能用了吧,一般前两 个动作都是通过观察者模式来完成的。

这个设计模式之后变种了一个发布/订阅的模式, 这个设计模式也是比较容易理解, 大家可以去了解下。

那观察者模式在什么情况下使用呢?观察者可以实现消息的广播,一个消息可以触发多个事件,这是 观察者模式非常重要的功能。使用观察者模式也有两个重点问题要解决:

  • 广播链的问题

如果你做过数据库的触发器,你就应该知道有一个触发器链的问题,比如表 A 上写了 一个触发器,内容是一个字段更新后更新表 B 的一条数据,而表 B 上也有个触发器,要更新表 C,表 C 也有触发器...,完蛋了,这个数据库基本上就毁掉了!我们的观察者模式也是一样的问题,一个观察者可以有双 重身份,即使观察者,也是被观察者,这没什么问题呀,但是链一旦建立,这个逻辑就比较复杂,可维护性非常差,根据经验建议,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消 息最多转发一次(传递两次),这还是比较好控制的;

  • 异步处理问题

被观察者发生动作了,观察者要做出回应,如果观察者比较多,而且处理时间比较长怎么办?那就用异步呗,异步处理就要考虑线程安全和队列的问题,这个 大家有时间看看 Message Queue,就会有更深的了解。

本文为作者原创,手码不易,允许转载,转载后请以链接形式说明文章出处。

目录
相关文章
|
3月前
|
设计模式 前端开发 数据中心
设计模式之观察者模式
设计模式之观察者模式
|
4月前
|
设计模式 存储 Java
认真学习设计模式之观察者模式(Observer Pattern)
认真学习设计模式之观察者模式(Observer Pattern)
31 0
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
6月前
|
设计模式 供应链
行为型设计模式03-观察者模式
行为型设计模式03-观察者模式
35 0
|
21天前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
|
1月前
|
设计模式 存储 Java
【设计模式】观察者模式
【设计模式】观察者模式
|
4月前
|
设计模式 存储 Java
Java设计模式【二十】:观察者模式
Java设计模式【二十】:观察者模式
26 0
|
3月前
|
设计模式 Java Spring
设计模式之观察者模式
设计模式之观察者模式
26 0
|
3月前
|
设计模式 算法 自动驾驶
常见的设计模式(模板与方法,观察者模式,策略模式)
随着时间的推移,软件代码越来越庞大,随着而来的就是如何维护日趋庞大的软件系统。在面向对象开发出现之前,使用的是面向过程开发来设计大型的软件程序,面向过程开发将软件分成一个个单独的模块,模块之间使用函数进行组合,最后完成系统的开发,每次需要修改软件,如果不涉及好各个模块的关系,就会导致软件系统难以维护,从而导致软件变得不可使用。面向对象方法用对象模拟问题域中的实体,以对象间的联系刻画实体间联系
67 2
|
3月前
|
设计模式 前端开发 NoSQL
聊聊Java设计模式-观察者模式
观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
66 0
聊聊Java设计模式-观察者模式