文档章节

从Yii2登陆中看PHP的工厂模式

卖小女孩的小火柴
 卖小女孩的小火柴
发布于 2015/05/25 20:01
字数 861
阅读 2308
收藏 29

首先,简单介绍下工厂模式:

在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。

工厂模式 是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。

1、首先,我们来实现一个简单的工厂模式,代码如下:

<?php
 
/*
 * PHP设计模式
 * 工厂模式
 */
 
/**
 * 接口
 */
interface Iuser {
 
    function getName();
 
    function getAge();
}
 
/**
 * 接口实现
 */
class User implements Iuser {
 
    public $uid;
    public $user_list = array(
        '1' => array(
            'name' => 'ken',
            'age' => '32'
        ),
        '2' => array(
            'name' => 'nices',
            'age' => '13'
        ),
    );
    public $user;
 
    public function __construct($uid) {
        $this->uid = $uid;
        if (in_array($uid, array(1, 2))) {
            $this->user = $this->user_list[$uid];
        }
    }
 
    public function getName() {
        return $this->user['name'];
    }
 
    public function getAge() {
        return $this->user['age'];
    }
 
}
 
class Studenty {
 
    public function getInfo($uid) {
        return new User($uid);
    }
 
}
 
$studenty = new Studenty();
$sInfo = $studenty->getInfo(2);
echo $sInfo->getName();
echo $sInfo->getAge();

2、工厂模式有了,但是这样的工厂模式调用不是很方便,每次都需要去new,然后我们可以采用静态调用的方式,这样就不需要每次都去new一下了,并且调用更加方便

<?php
 
/*
 * PHP设计模式
 * 工厂模式变种
 */
 
interface Iuser {
 
    public function getName();
 
    public function getAge();
}
 
class User implements Iuser {
 
    public $uid;
    public $user_list = array(
        '1' => array(
            'name' => 'ken',
            'age' => '32'
        ),
        '2' => array(
            'name' => 'nices',
            'age' => '13'
        ),
    );
    public $user;
 
    public static function Load($uid) {
        return new User($uid);
    }
 
    public function __construct($uid) {
        if (in_array($uid, array(1, 2))) {
            $this->uid = $uid;
            $this->user = $this->user_list[$uid];
        }
    }
 
    public function getName() {
        return $this->user['name'];
    }
 
    public function getAge() {
        return $this->user['age'];
    }
 
}
 
$user = User::Load(2);
echo $user->getName();

通过这样的工厂模式,我们可以很方便的使用静态方法User::Load进行调用。

3、那么Yii2中的登录又是如何的乃?

<?php

namespace app\models;

use Yii;

class User extends \yii\base\Object implements \yii\web\IdentityInterface

这段代码是Yii2中的User模型中的代码,这里使用了接口IdentityInterface类,细心的朋友会去查看\yii\web\IdentityInterface中的代码,这就是一个标准的接口

interface IdentityInterface
{
    /**
     * 为了减少篇幅,我去掉了注释,这段代码可以从Yii2中获取
     */
    public static function findIdentity($id);
    public static function findIdentityByAccessToken($token, $type = null);
    public function getId();
    public function getAuthKey();
    public function validateAuthKey($authKey);
}

User模型使用了该接口,那么久必须要进行一些方法的声明使用,在app\models\User中即可看到。部分代码如下:

<?php

namespace app\models;

class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
    public $id;
    public $username;
    public $password;
    public $authKey;
    public $accessToken;

    private static $users = [
        '100' => [
            'id' => '100',
            'username' => 'admin',
            'password' => 'admin',
            'authKey' => 'test100key',
            'accessToken' => '100-token',
        ],
        '101' => [
            'id' => '101',
            'username' => 'demo',
            'password' => 'demo',
            'authKey' => 'test101key',
            'accessToken' => '101-token',
        ],
    ];

    /**
     * @inheritdoc
     */
    public static function findIdentity($id)
    {
        return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
    }

    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        foreach (self::$users as $user) {
            if ($user['accessToken'] === $token) {
                return new static($user);
            }
        }

        return null;
    }
    
    ......

Yii2中的使用是非常灵活的,并且继承了\yii\base\Object。

总结:工厂模式是设计模式中的一种很常用的设计模式,在很多大型应用中非常常见。Yii2中还有很多地方使用了工厂模式,比如依赖注入DI等,有兴趣的童鞋可以了解下。


© 著作权归作者所有

卖小女孩的小火柴
粉丝 46
博文 68
码字总数 28535
作品 1
成都
项目经理
私信 提问
加载中

评论(7)

水露露
水露露
yii 越来越像java了
卖小女孩的小火柴
卖小女孩的小火柴 博主

引用来自“清秋-a”的评论

yii2里面没有findById这个方法,而是直接findOne,这不是重点,重点是你查出来的本就是user对象了,你再new 一次是个什么意思呢
感谢指出错误,已修正
清秋-a
清秋-a
yii2里面没有findById这个方法,而是直接findOne,这不是重点,重点是你查出来的本就是user对象了,你再new 一次是个什么意思呢
卖小女孩的小火柴
卖小女孩的小火柴 博主

引用来自“清秋-a”的评论

模型有写错了.
?
清秋-a
清秋-a
模型有写错了.
卖小女孩的小火柴
卖小女孩的小火柴 博主

引用来自“Tuesday”的评论

终于明白php为什么跌出排行榜前十了..
何解?
Tuesday
Tuesday
终于明白php为什么跌出排行榜前十了..
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
2018/11/06
166
0
JS单例模式《JavaScript设计模式与开发实践》阅读笔记

此文仅记录本人阅读《JavaScript设计模式与开发实践》这个本时的感受,感谢作者曾探写出这么好的一本书。如有冒犯,如有错误,请联系本人:luogao_lg@sina.com处理。 这一章让我知道了单例模...

RoyLuo
2018/05/17
0
0
PHP设计模式(一):简介及创建型模式

我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式。 一、设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用、容易被他人理解的、可靠的代码设...

juhenj
2014/05/15
269
2
java的回调函数,本身算是工厂模式吗?

一直以来都没怎么学习过设计模式 今天在详细了解java的工厂模式时,意外的觉得这货不就是回调函数吗? java的回掉函数,可以用抽象类或是接口实现。而今天从《设计模式之禅》中看的工厂模式,...

优秀良民
2016/05/08
240
2
编程中的那些套路——关于单例模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 在设计模式中,单例模式和工厂模式)可以说是使用的最普遍的设计模式了,所以掌握此种模式尤为重要。 单...

gzchen
2018/08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud 笔记之Spring cloud config client

观察者模式它的数据的变化是被动的。 观察者模式在java中的实现: package com.hxq.springcloud.springcloudconfigclient;import org.springframework.context.ApplicationListener;i...

xiaoxiao_go
今天
4
0
CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
今天
4
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
今天
7
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
今天
7
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部