北京做视觉网站/企业培训机构

北京做视觉网站,企业培训机构,哪个网站做自行车评测的,深圳最好的品牌设计公司php 设计模式之工厂模式、单例模式、注册树模式在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具体说是向设计中增加复杂度,创建型…

php 设计模式之工厂模式、单例模式、注册树模式

在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具体说是向设计中增加复杂度,创建型设计模式解决了程序设计中对象创建的问题。PHP的设计模式有很多种,本文取最简单的三种模式: 工厂模式、单例模式和注册树模式进行简单的讲解。

工厂模式

用工厂方法或者类生成对象,而不是代码中直接使用 new 关键字

比如咱们要做一个连接数据库的操作,平时都是用mysql。那突然有一天mysql收费了,咋办?那我们就用Sqlite作来数据库。如果以传统的方式创建一个数据库连接类的话是需要使用关键字new MysqlDrive()把这个数据库实例化,一旦数据库变更成的话就需要把所有的new MysqlDrive()变更成new SqliteDrive() 这样替换比较麻烦,并且还容易出错。所以,下面的工厂模式可以很好的解决这一问题。

废话不多说,演示一遍就明白了

先看一下目录结构吧本文演示的全部是遵循PSR-4的编码规范,当然,是在vendor/目录下,如果没有请自己行执行命令composer dumpatuoload 如果您没有安装composer那就请看下面文章:

以下是我的目录结构:

287c458a2968e1e0eeaeba18fe7ba8f1.png

自动忽略DependencyInjection 跟HttpFoundation目录,这是我计划下次写的东西,嘻嘻...

先看看主要文件的代码吧:

tests/这个目录是为了让咱们方便测试的目录,也就是单元测试目录

文件: tests/bootstrap.php

include_once __DIR__."/../../../composer/ClassLoader.php";

$loader = new \Composer\Autoload\ClassLoader();

$vendorDir = dirname(dirname(__FILE__));

$baseDir = dirname($vendorDir);

$classMaps = [

'Dudulu\\' => [$vendorDir."/src/"]

];

foreach ($classMaps as $namespace => $path) {

$loader->setPsr4($namespace, $path);

}

$loader->register(true);

咱们需要测试的驱动类MysqlDerive.php

文件: src/DesignPatterns\FactoryMode\DB\MysqlDrive.php

namespace Dudulu\DesignPatterns\FactoryMode;

use Dudulu\DesignPatterns\DB\MysqlDrive;

/**

* Class Factory

* @package Dudulu\DesignPatterns\FactoryMode

*/

class Factory

{

/**

* @return MysqlDrive

*/

public static function database()

{

return new MysqlDrive();

}

}

为了强制让每种驱动都要有一个连接方式,所以我们需要一个Interface。

文件: src/DesignPatterns/DB/Interfaces/DriveInterface.php

namespace Dudulu\DesignPatterns\DB\Interfaces;

/**

* Interface DriveInterface

* @package Dudulu\DesignPatterns\DB\Interfaces

*/

interface DriveInterface

{

/**

* @return mixed

*/

public function connection();

}

普通模式

先看一个普通demo,直接实例化MysqlDrive对象

include_once "../bootstrap.php";

use Dudulu\DesignPatterns\DB\MysqlDrive;

class FactoryTest extends PHPUnit_Framework_TestCase {

public function testConnection()

{

$db = new MysqlDrive();

$this->assertEquals(true, $db->connection());

}

}

进入src/tests/DesignPattens目录.

命令行执行: phpunit FactoryTest.php可以发现这样是好使的...

工厂模式

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

首先咱们先创建一个Factory.php作为工厂类,然后里边实现一个静态方法对相数据库驱动进行实例化。

文件: src/DesignPatterns/FactoryMode/Factory.php

namespace Dudulu\DesignPatterns\FactoryMode;

use Dudulu\DesignPatterns\DB\MysqlDrive;

/**

* Class Factory

* @package Dudulu\DesignPatterns\FactoryMode

*/

class Factory

{

/**

* @return MysqlDrive

*/

public static function database()

{

return new MysqlDrive();

}

}

创建完后,咱们回到单元测试文件FactoryTest.php

文件: tests/DesignPattens/FactoryTest.php

include_once "../bootstrap.php";

use Dudulu\DesignPatterns\FactoryMode\Factory;

class FactoryTest extends PHPUnit_Framework_TestCase {

public function testConnection()

{

$db = Factory::database();

$this->assertEquals(true, $db->connection());

}

}

再执行一下单元测试命令发现,也能返回成功,这样的话我们就能很方便的修改任何驱动了。如果我们从mysql换到sqlite了,那么,咱们主要的代码都不需要更变,只要在Factory.php把connection方法的边接方式修改完就好了,非常方便。

单例模式

使某个类的对象仅允许创建一个

某些应用程序资源是独占的,因为有且只有一个此类型的资源。比如,数据库的连接的独占。希望在应用程序中共享数据库连接,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更是如此。

比如咱们连接数据库时,如果不使用单例模式,多个地方都对数据类进行了实例化,那么这样会造能很多资源浪费,为了解决这问题,对于数据库类我们只需要实例化一次,后面再次调用它是如果已经实例化,那就直接返回。

来,我们拿一个类来玩一玩...

文件: src/DesignPatterns/SingletonMode/SingletonDB.php

我们创建这个类,然后将构造方法私有化,这样的话我们就无法使用new关键字对这个类进行实例化了。

namespace Dudulu\DesignPatterns\SingletonMode;

use Dudulu\DesignPatterns\DB\Interfaces\DriveInterface;

/**

* Class SingletonDB

* @package Dudulu\DesignPatterns\SingletonMode

*/

class SingletonDB implements DriveInterface

{

/**

* SingletonDB constructor.

*/

private function __construct()

{

}

/**

* @return bool

*/

public function connection()

{

return true;

}

}

那么我们要如何使用这个对象呢?我们需要一个受保护的成员和一个静态方法:

/**

* @var SingletonDB

*/

protected static $db;

/**

* @return SingletonDB

*/

public static function getInstance()

{

if (self::$db) {

return self::$db;

}

self::$db = new self();

return self::$db;

}

这个方法很好理解,简单意思就是如果当前属性已经被设置过了,那就不再进行实例化,而是直接返回,否则实例化当前对象并返回。

与测试上面的方法一样,测玩玩...

创建测试的文件: tests/DesignPattens/SingletonDBTest.php

include_once "../bootstrap.php";

use Dudulu\DesignPatterns\SingletonMode\SingletonDB;

/**

* Class SingletonDBTest

*/

class SingletonDBTest extends PHPUnit_Framework_TestCase

{

/**

* @return void

*/

public function testConnection()

{

$db = SingletonDB::getInstance();

$this->assertEquals(true, $db->connection());

}

}

执行命令: phpunit SingletonDBTest.php 发现也是可以执行成功的。

如果不信的话,你可以试试多执行几次SingletonDB::getInstance(); 然后在 getInstance() 方法体里做一个计数器,看看它实例化过几次。

注册树模式

主要用来解决全局共享和交换对象

这个也很好理解,因为我们在框架中经常用到。

注册树模式当然也叫注册模式,注册器模式。之所以我在这里矫情一下它的名称,是因为我感觉注册树这个名称更容易让人理解。注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法。

咱们结合工厂模式及单例模式做一个小例子:

创建文件: src/DesignPatterns/RegisterMode/Register.php

namespace Dudulu\DesignPatterns\RegisterMode;

/**

* Class Register

* @package Dudulu\DesignPatterns\RegisterMode

*/

class Register

{

/**

* @var array

*/

protected static $classMaps = [];

/**

* @param $alias

* @param $class

* @return void

*/

public static function set($alias, $class )

{

self::$classMaps[$alias] = $class;

}

/**

* @param $alias

* @return mixed

*/

public static function get($alias )

{

return self::$classMaps[$alias];

}

}

然后创建一个单例模式的DB类DemoDB.php:

文件: src/DesignPatterns/DB/DemoDB.php

namespace Dudulu\DesignPatterns\DB;

use Dudulu\DesignPatterns\DB\Interfaces\DriveInterface;

class DemoDB implements DriveInterface

{

/**

* @var DemoDB

*/

protected static $db;

/**

* SingletonDB constructor.

*/

private function __construct()

{

}

/**

* @return DemoDB

*/

public static function getInstance()

{

if (self::$db) {

return self::$db;

}

self::$db = new self();

return self::$db;

}

/**

* @return bool

*/

public function connection()

{

return true;

}

}

再工厂模式文件上加入注册方式代码:

文件: src/DesignPatterns/FactoryMode/Factory.php

use Dudulu\DesignPatterns\RegisterMode\Register;

/**

* @return DemoDB

*/

public static function testDb()

{

$db = DemoDB::getInstance();

Register::set('DB', $db);

return $db;

}

最后咱们验证一下:

在tests/目录下创建RegisterTest.php文件

include_once "../bootstrap.php";

use Dudulu\DesignPatterns\RegisterMode\Register;

use Dudulu\DesignPatterns\DB\DemoDB;

/**

* Class RegisterTest

*/

class RegisterTest extends PHPUnit_Framework_TestCase

{

/**

* @return void

*/

public function testConnection()

{

Register::set('DB', DemoDB::getInstance());

$db = Register::get('DB');

$this->assertEquals(true, $db->connection());

}

}

OK 走一个phpunit RegisterTest.php

ab1fb361a1af90ac9323f134751ba72f.png

返回OK,好棒好棒...☆〜(ゝ。∂)

__

/ )))    _

`/ イ~   (((ヽ

(  ノ      ̄Y\

| (\ ∧_∧ | )

ヽ ヽ`( `o´ )/ノ/

\ | ⌒Y⌒ / /

|ヽ  |  ノ/

\トー仝ーイ

如果有时间,下次我再写些关于其他设计模式的文章...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 正则匹配unicode,PHP中正则表达式对UNICODE字符码的匹配方法

网友ainiaa的问题是PHP代码如下代码如下:$words "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!#$%^&*()_-[]\\,./{}|<>?\"你好啊我们";$otherStrpreg_replace("/[chr(128)-chr(256)]/is"," ",$words);ech…

iis7怎么安装php7,Linux下如何安装php7

Linux下安装php7的方法&#xff1a;首先安装依赖包&#xff0c;并下载解压安装包&#xff1b;然后检查环境的依赖关系&#xff0c;并编译安装&#xff1b;接着将【php.ini-production】改名为【php.ini】&#xff1b;最后复制启动脚本&#xff0c;并启动PHP即可。Linux下安装ph…

flux react php,Vue的Flux框架之Vuex状态管理器

学习vue之前&#xff0c;最重要是弄懂两个概念&#xff0c;一是“what”&#xff0c;要理解vuex是什么&#xff1b;二是“why”,要清楚为什么要用vuex。Vuex是什么&#xff1f;Vuex 类似 React 里面的 Redux 的状态管理器&#xff0c;用来管理Vue的所有组件状态。为什么使用Vue…

php在类定义一个我静态变量,php中静态类与静态变量用法的区别分析_PHP教程

php中静态类与静态变量用法的区别分析static是定义一个静态对象或静态变量,关于static 定义的变量或类方法有什么特性我们看完本文章的相关实例后就见分晓了.1. 创建对象$object new Class()&#xff0c;然后使用”->”调用&#xff1a;$object->attribute/function&…

matlab声音信号时域频域转换,关于处理用采集卡采集到的声音时域信号转化成频域信号........

求助各位大神&#xff0c;我用麦克风通过采集卡采集到了一段声音数据&#xff0c;数据在附件里&#xff0c;矩阵中第一列为时间&#xff0c;第二列为采集到的声音的电压信号&#xff0c;采样频率为1万Hz&#xff0c;做出时域图和频域图的程序如下所示&#xff1a;clear;clc;loa…

win7和mysql乱码,windows本地mysql数据库存入中文乱码

windows本地mysql数据库存入中文乱码作者:PHPYuan 时间:2018-07-23 03:41:20出现的问题&#xff1a; 我这页面存中文到数据库会乱码 我打了断点 中文是传到后台dao层的 然后我试了下 把我本地项目连服务器数据库 保存不会乱码 我就怀疑是本地数据库有问题 然后我用navicat写了个…

oracle 600 侯,oracle在导入数据时报600错误的解决方法

前言前几天导入一个大容量dmp数据文件&#xff0c;报一个600错误&#xff0c;咨询网上的解决方法&#xff0c;按上面的处理一圈也没有整好&#xff0c;最后咨询组里一个大神&#xff0c;出现此错误 思路是&#xff0c;单个数据文件大小最大为32G&#xff0c;分析数据库后解决如…

Oracle插数据timeout,oracle 11g 频繁报kmgs_parameter_update_timeout

各位 好&#xff01;我的数据库RAC 11g 最近频繁报错&#xff0c;数据库版本是11.2.0.1.0 详细错误信息如下&#xff1a;Errors in file /u01/app/oracle/diag/rdbms/glddb/glddb1/trace/glddb1_mmon_27429.trc (incident123874):ORA-00600: internal error code, arguments: …

linux touch更新文件时间,Linux文件时间的查看和修改touch

1. Linux文件的时间Linux下文件时间主要有下面三种&#xff1a;1.1 modification time(mtime)文件修改时间&#xff0c;即文件内容的修改时&#xff0c;更新这个时间&#xff0c;不包括文件权限和属性的修改。使用ls -l查看&#xff0c;默认显示时间为mtime$ ls -l uconv.h-rw-…

linux中ftp禁止匿名,linux下禁止root和匿名用户登录ftp

1、ftp通过root或其他用户进入可视化界面权限过大&#xff0c;容易导致系统文件误删windows下输入ftp://IP去访问&#xff0c;不需要账号密码就可以访问到ftp文件夹刚进去pub是空的&#xff0c;在linux上新增一个txt文件&#xff0c;再去windows下刷新可以看到txt文件&#xff…

mats显存测试软件linux环境,Mats显存检测软件下载-Mats显存检测软件最新版下载-微侠手游网...

Mats显存检测软件是一款专业的显卡检测工具&#xff0c;全系统都是中文的&#xff0c;是一款装机必备的硬件工具&#xff0c;帮助你了解自己的显卡运作情况&#xff0c;有任何问题都可以第一时间暂停&#xff0c;看完的小伙伴可以关注微侠网下载最新版软件以及查看最新攻略及资…

c语言编程函数补充上机题,2011年计算机二级C语言上机操作题及答案(10)

/********found********/void fun(char *s, *t1, *t2, *w){int i;char *p, *r, *a;strcpy(w, s);while (*w){p w;r t1;/********found********/while (r)if (*r *p){r;p;}else{break;}if (*r ’\0’){a w;r t2;while (*r){*a *r;a;r;}w strlen(t2);}else{w;}}}main(…

c语言 手机图形库,c语言的图形库 - osc_opiar5rp的个人空间 - OSCHINA - 中文开源技术交流社区...

图形库链接http://www.easyx.cn/ 使用图形库头文件easyx.h或graphics.h同样在里面下载图形库帮助文档进行查询vs vc都可使用图形库图形库窗口&#xff1a;initgraph打开窗口closegraph关闭窗口颜色RGB值 RGB(,,)&#xff1a;red green blue 下表值都可以在函数中直接使用填充颜…

android 自动挂断,[转]android 来电自动接听和自动挂断

注意&#xff1a;android2.3版本不支持下面的自动接听方法。(会抛异常&#xff1a;java.lang.SecurityException:Neither user xxxxx nor current process hasandroid.permission.MODIFY_PHONE_STATE.)第一步&#xff1a;准备应用环境需要的系统包和aidl文件。(1)在应用中创建包…

Android实现mp3分析,Android编程实现播放MP3功能示例

本文实例讲述了Android编程实现播放MP3功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;在android中播放mp3非常简单&#xff0c;也是项目中经常使用的&#xff0c;比如说要做项目的背景音乐&#xff0c;应用中某些功能的提示音等的。应用非常广泛,下面提供一个简单…

android 投票功能,腾讯新闻Android客户端更新 加入投票功能

腾讯近日更新了其应用《腾讯新闻》安卓版&#xff0c;加入了新闻专题&#xff0c;投票两大新功能&#xff0c;同事还优化了用户界面&#xff0c;大家在浏览各类新闻方面又有了新的选择。新版特点&#xff1a;1、新闻专题&#xff1a;热门新闻专题呈现&#xff0c;聚合浏览&…

android8.1自定义通知栏,Android 8.1隐藏状态栏图标的实例代码

近期客户需求&#xff0c;状态栏只显示时间和电池图标&#xff0c;如图状态栏图标的布局文件在frameworks\base\packages\SystemUI\res\layout\status_bar.xml,主要包括通知&#xff0c;定位&#xff0c;蓝牙&#xff0c;信号&#xff0c;时间&#xff0c;电池等图标&#xff0…

广州城市地图为android,广州无障碍地图

广州无障碍地图是一款非常不错的手机导航app&#xff0c;专门为老人与残障人士打造的哦。该app将准确的为残障用户规划出一条没有任何障碍的出行路线&#xff0c;并且该软件拥有语音、文字等不同的播报方式。特色说明1、智能化的手机导航的系统&#xff0c;语音识别2、最为准确…

华为副总鸿蒙,“哄蒙”败北!华为副总裁落实最新消息,鸿蒙3月31日正式亮剑...

原标题&#xff1a;“哄蒙”败北&#xff01;华为副总裁落实最新消息&#xff0c;鸿蒙3月31日正式亮剑不得不说&#xff0c;最近的华为生态建设又取得了重大的突破。在2020年不到一年的时间里&#xff0c;华为HMS生态注册开发者的数量就已经快要突破200万了&#xff0c;如此庞大…

html淡化效果,jQuery实现基本淡入淡出效果的方法详解

本文实例讲述了jQuery实现基本淡入淡出效果的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;jQuery fadeIn()方法&#xff1a;用于淡入已隐藏的元素jQuery fadeOut()方法&#xff1a;用于淡出可见的元素$(document).ready(function(){$("button").clic…