`
xieye
  • 浏览: 831298 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

php设计模式(2)-- 观察者模式 -- 用trait来改进的写法

    博客分类:
  • PHP
阅读更多
我的设计模式系列文章
php设计模式(1)-- 观察者模式 -- spl标准写法
php设计模式(2)-- 观察者模式 -- 用trait来改进的写法
php设计模式(3)-- 责任链(职责链)模式
php设计模式(4)-- 装饰器模式


分析

我们来重新思考一下前面的代码,发现有一个不足,我仅仅是想实现观察者,如果每个想实现观察者的类,都写那么多代码,不太好。
这里我不使用继承,原因:php只允许单继承,如果为了实现观察者模式继承的话,就不能继承别的类了。

于是使用trait来解决,效果棒呆!对于前文的4个文件,修改User.php,再添加一个MySqlSubject.php,这样的话,两个观察者类,和客户端代码无需任何修改,

最终,User类的代码只有他自己的业务逻辑,无关的代码被放到通用类MySqlSubject中,代码十分清爽,且可以重用。

代码

MySplSubject.php
<?php
// 本类是可以通用的
trait MySplSubject {

    /**
     * @var SplObjectStorage
     */
    private $observers = NULL;

    private function create_observers(){
        if ($this->observers==null) {
            $this->observers = new SplObjectStorage();
        }
    }
    
    public function attach(SplObserver $observer) {
        $this->create_observers();
        $this->observers->attach($observer);
    }

    public function detach(SplObserver $observer) {
        $this->create_observers();
        $this->observers->detach($observer);
    }

    public function notify() {
        $this->create_observers();
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }

}


User.php
<?php

class User implements SplSubject {
    // 由trait来实现接口
    use MySplSubject;
    
    private $email;
    private $username;
    private $mobile;
    private $password;
    

    public function __construct($email, $username, $mobile, $password) {
        $this->email = $email;
        $this->username = $username;
        $this->mobile = $mobile;
        $this->password = $password;

    }

    // 这是业务逻辑
    public function changePassword($newPassword) {
        echo __METHOD__, PHP_EOL;
        $this->password = $newPassword;
        $this->notify();
    }

    // 专门给监听器的信息,也可以省略,然后对每个字段添加get方法
    public function get_observer_info(){
        return [
            "email" => $this->email,
            "mobile" => $this->mobile,
            "username" => $this->username,
            "password" =>$this->password,
        ];
    }

}


效果展示同前文一样:
User::changePassword
向 user1@domain.com 发送电子邮件成功。内容是:你好 张三你的新密码是 654321,请妥善保管
向 手机13610002000 发送短信成功。短信内容是:你好 张三你的新密码是 654321,请妥善保管

0
0
分享到:
评论

相关推荐

    Laravel开发-artisan-trait-maker

    在Laravel框架中,开发者经常会使用Traits来复用代码,这是一种强大的PHP特性,允许你在类中"导入"其他类的方法。本教程将深入探讨如何利用Artisan命令行工具创建自定义的Trait存根,以便更高效地管理和组织项目中的...

    Laravel开发-laravel-trait-uuid

    `laravel-trait-uuid`是专门为Laravel设计的一个特性(Trait),用于方便地在Eloquent模型中实现UUID作为主键的功能。 本文将详细讲解如何使用`laravel-trait-uuid`来在Laravel项目中集成UUID,并探讨其背后的工作...

    Laravel开发-trait-maker

    在Laravel框架中,trait是一种代码复用机制,它允许开发者将一组方法插入到类中,而无需使用继承。Trait Maker是Laravel开发中的一个工具,它提供了一个 artisan 命令来帮助开发者快速创建trait的存根文件,从而简化...

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术计模式.mp4

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术计模式.mp4

    Laravel开发-laravel-trait-updatedby

    `laravel-trait-updatedby` 是一个专门为Laravel设计的特性(Trait),它帮助开发者方便地在Eloquent ORM(对象关系映射)模型中自动添加或更新`updated_by`字段,这个字段通常用来存储最后更新数据的用户的ID。...

    Laravel开发-laravel-sluggable-trait

    默认的冲突解决方法是通过在slug末尾添加递增的数字来避免重复,如`example-1`、`example-2`等。当然,你还可以自定义冲突解决方法。 在实际应用中,`laravel-sluggable-trait`不仅可以简化slug的生成,还可以提高...

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术代码复用.mp4

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术代码复用.mp4

    Laravel开发-eloquent-model-trait

    Laravel开发-eloquent-model-trait 为雄辩模型添加有用的方法

    Laravel开发-laravel-create-update-trait

    2. **使用Trait** 要在你的控制器或其他类中使用trait,只需在类声明中使用`use`关键字,如下: ```php namespace App\Http\Controllers; use App\Traits\CreateUpdate; use Illuminate\Http\Request; ...

    Laravel开发-addressable-trait

    `addressable-trait`就是一个专门为Laravel 5.1设计的特性,它旨在简化模型对象与地址管理的集成。这个特性使得我们可以方便地在模型上添加、编辑和管理地址信息,无需在每个模型中重复编写相同的功能代码。 首先,...

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术er安装TP51_Win版.mp4

    计算机后端-PHP大牛线上培训班课-HP设计模式与Trait技术er安装TP51_Win版.mp4

    Laravel开发-trait-maker .zip.zip

    如果一个类同时使用了两个Trait,而它们有同名的方法,可以使用`insteadof`和`as`关键字来解决命名冲突。`insteadof`用于指定在冲突时使用哪个Trait的方法,`as`用于重命名冲突的方法。 5. **Trait与接口**: ...

    Laravel开发-laravel-bitwise-trait

    在实际应用中,你可以将这个trait引入到你的Eloquent模型或其他类中,然后使用上述方法来处理位字段。例如,如果你有一个`Role`模型,其中`permissions`字段是位字段,你可以轻松地添加、删除或检查角色的权限: ``...

    yii2-crud-trait:Yii2 带有 php 特性的简单 CRUD

    "yii2-crud-trait" 是一个专门为 Yii2 框架设计的特性,旨在简化这些基本操作的实现,提高开发效率。 首先,我们来理解一下什么是 Trait。在 PHP 中,Trait 是一种代码复用机制,它允许你将一组方法插入到一个类中...

    PHP5设计模式电子教程PDF全书

    观察者模式在事件驱动编程中非常常见。它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在PHP中,可以使用 SPL(Standard PHP Library)中的 SplSubject...

    Laravel开发-laravel-encryptable-trait

    2. **查询操作**:在进行查询时,你不能直接使用加密字段进行比较,因为它们在数据库中的形式是加密后的。你需要先解密数据再进行比较。 3. **数据库字段类型**:由于加密后的数据通常包含随机字符,所以最好将这些...

    Laravel开发-validation-trait

    在Laravel框架中,Validation Trait是一个非常重要的工具,它使得数据验证变得更加简洁和高效。这个特质(trait)被广泛应用于控制器中,以处理输入数据的验证逻辑,确保应用程序接收到的数据是安全、完整且符合预期...

    PHP中用Trait封装单例模式的实现

    在本篇文章中,我们将探讨如何使用PHP的Trait特性来封装单例模式,从而简化代码并提高代码的可复用性。 首先,理解单例模式的基本原则。单例模式遵循以下四个步骤: 1. **私有化静态属性**:创建一个私有的静态成员...

Global site tag (gtag.js) - Google Analytics