PHP设计模式(一),PHP设计模式(_PHP教程
PHP设计模式(一),PHP设计模式(
在码PHP程序的时候,为了以后更好地维护代码和理解代码,用一些合适的设计模式是必不可少的,下面我和大家首先分享下单例模式,有错误或者不恰当的地方,还望PHPer们帮我指出。
- 单例模式
PHP中的对象生存期间是从该脚本开始一直到该脚本结束为止,因此PHP的单例模式只是在一个页面中(这里可能包含很多其他页面,不是狭义的单页面)多次用到该对象时才会起作用,多次用到时不去重复的new对象(多个人做一个项目时,难免会碰到一次请求中多次实例一个对象的情况),将不会耗费不必要的资源(数据控连接操做效果很明显),还有一点就是可以保证整个脚本中都是同一个对象,这种模式是怎么实现的呢,他的实现有几个要注意的点:
1. 首先就是要将__construct()方法定义为私有方法,这样就不能通过new来得到一个新的实例了,单例模式不能在外部进行实例化,这能字自身内部进行实例化;
2. 同样要屏蔽__clone()方法,防止从类外部进行克隆
2. 然后就是定义一个用来保存实例的私有变量和获取私有变量的公有函数getInstance()。
<?<span>php </span><span>/*</span><span>* * 设计模式——单例模式 * @author 燕睿涛(luluyrt@163.com) </span><span>*/</span> <span>class</span><span> Singlemodel{ </span><span>/*</span><span>* * 保存Singlemodel实例的变量 * @var Singlemodel $_instance </span><span>*/</span> <span>private</span> <span>static</span> <span>$_instance</span> = <span>null</span><span>; </span><span>/*</span><span>* * 屏蔽掉通过new来实例化该对象 </span><span>*/</span> <span>private</span> <span>function</span><span> __construct(){ </span><span>//</span><span>空函数就行</span> <span> } <span> /*</span><span>*</span></span>
<span><span> * 屏蔽掉通过clone来克隆该对象</span></span>
<span><span>*/</span> </span>
<span> <span>private</span> <span>function</span><span> __clone(){ </span></span>
<span><span>//</span><span>空函数就行</span> </span>
<span> <span>}</span> </span><span>/*</span><span>* * 通过该方法获取实例,防止多次实例化 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> getInstance(){ </span><span>if</span>(!(self::<span>$_instance</span><span> instanceof self)){ self</span>::<span>$_instance</span> = <span>new</span><span> self(); } </span><span>return</span> self::<span>$_instance</span><span>; } }</span>
空口无凭,光说这些理论的没有说服力,下面通过例子来看下具体的效果差异
<?<span>php </span><span>/*</span><span>* * 设计模式——单例模式——测试 * @author 燕睿涛(luluyrt@163.com) </span><span>*/</span> <span>class</span><span> Singlemodel{ </span><span>/*</span><span>* * 保存Singlemodel实例的变量 * @var Singlemodel $_instance </span><span>*/</span> <span>private</span> <span>static</span> <span>$_instance</span> = <span>null</span><span>; </span><span>private</span> <span>$_link</span> = <span>null</span><span>; </span><span>/*</span><span>* * 屏蔽掉通过new来实例化该对象(也可以去掉) * 这里来测试数据库连接 </span><span>*/</span> <span>private</span> <span>function</span><span> __construct(){ </span><span>$this</span>->_link = <span>mysqli_connect</span>("localhost","root","","mysql"<span>); } </span><span>/*</span><span>* * 通过该方法获取实例,防止多次实例化 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> getInstance(){ </span><span>if</span>(!(self::<span>$_instance</span><span> instanceof self)){ self</span>::<span>$_instance</span> = <span>new</span><span> self(); } </span><span>return</span> self::<span>$_instance</span><span>; } </span><span>/*</span><span>* * 测试1,通过使用单例模式 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> testOne(){ </span><span>return</span> self::<span>getInstance(); } </span><span>/*</span><span>* * 测试1,通过使用单例模式 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> testTwo(){ </span><span>return</span> <span>new</span><span> self(); } } </span><span>$obj</span> = <span>array</span><span>(); </span><span>$begin</span> = <span>microtime</span>(<span>true</span><span>); </span><span>for</span>(<span>$i</span>=0;<span>$i</span><100;<span>$i</span>++<span>){ </span><span>/*</span><span> * 这里进行两次测试,testOne应用了单例模式,testTwo没有应用单例模式, * 我们分别看看他们占用的资源和耗费的时间 </span><span>*/</span> <span>//</span><span>$obj[$i] = Singlemodel::testOne();</span> <span>$obj</span>[<span>$i</span>] = Singlemodel::<span>testTwo(); } </span><span>echo</span> "程序运行期间最大内存占用:".memory_get_peak_usage()."bytes\r"<span>; </span><span>echo</span> "程序运行耗时:".<span>floatval</span>(<span>microtime</span>(<span>true</span>) - <span>$begin</span>)."s\r";
先注释$obj[$i] = Singlemodel::testTwo();这一行,使用单例模式,我们可以得到下面的结果
$obj[$i] = Singlemodel::testOne();,使用非单例模式,我们得到下面结果
可以看到
100次测试 | 单例模式 | 普通模式 | 普通/单例(倍) |
内存(bytes) | 143816 | 847376 | 5.89 |
时间(s) | 0.0112519 | 0.2541389 | 22.59 |
5次测试 | |||
bytes | 140432 | 168984 | 1.20 |
s | 0.0112612 | 0.0173110 | 1.54 |
可以看到当一次脚本执行的链接数为100时单例模式的性能比普通模式在内存占用方面好了将近6倍,时间上快了将近23倍,当连接数继续增加的时候倍数会更大,因为单例模式耗费的内存和时间基本没有变化,非单例模式会不停地增大,这里要注意一点就是非单例模式情况下链接数增大到一定程度时会报错"mysqli_connect(): (08004/1040): Trop de connexions in",意思是说并发连接太多了,测试我们可以通过下面的命令查看mysql最大连接数设置,这点需要注意下,免得不知道为什么报错。
show variables <span>like</span> <span>'</span><span>max_connections</span><span>'</span>;
到这里,你要是自己测试过就会发现,当链接次数比较少时,差异是比较小的(就像上面的一次请求有5次连接时),其实在一次请求中达到很多次实例化也是比较少的,那么是不是说这个就没作用了呢,当然不是,你想想看,首先,这样可以尽量避免多次实例化,减小资源消耗;其次,就算是这10ms级的差距,在高并发系统中也是很有用的。我们用它好处多多。
单例模式就这么多了,下次再讲其他设计模式,有什么不对的地方还望留言或者邮件指出,感激不尽!
send Me~

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

在Java框架中,设计模式和架构模式的区别在于:设计模式定义了在软件设计中解决常见问题的抽象解决方案,关注类和对象之间的交互,如工厂模式。架构模式定义了系统结构和模块之间的关系,关注系统组件的组织和交互,如分层架构。

适配器模式是一种结构型设计模式,允许不兼容对象协同工作,它将一个接口转换为另一个,使对象能够顺利交互。对象适配器通过创建包含被适配对象的适配器对象,并实现目标接口,实现适配器模式。在一个实战案例中,通过适配器模式,客户端(如MediaPlayer)可以播放高级格式的媒体(如VLC),尽管其本身仅支持普通媒体格式(如MP3)。

装饰器模式是一种结构型设计模式,允许动态添加对象功能,无需修改原始类。它通过抽象组件、具体组件、抽象装饰器和具体装饰器的协作实现,可以灵活扩展类功能,满足变化的需求。示例中,将牛奶和摩卡装饰器添加到Espresso,总价为2.29美元,展示了装饰器模式在动态修改对象行为方面的强大功能。

1.工厂模式:分离对象创建和业务逻辑,通过工厂类创建指定类型的对象。2.观察者模式:允许主题对象通知观察者对象其状态更改,实现松耦合和观察者模式。

TDD用于编写高质量PHP代码,步骤包括:编写测试用例,描述预期功能并使其失败。编写代码,仅使测试用例通过,无需过分优化或详细设计。测试用例通过后,优化和重构代码以提高可读性、可维护性和可扩展性。

设计模式通过提供可重用和可扩展的解决方案来解决代码维护难题:观察者模式:允许对象订阅事件,并在事件发生时收到通知。工厂模式:提供了一种创建对象的集中式方式,而无需依赖具体类。单例模式:确保一个类只有一个实例,用于创建全局可访问的对象。

Java框架中使用设计模式的优点包括:代码可读性、可维护性和可扩展性增强。缺点包括:过度使用导致复杂性、性能开销以及学习曲线陡峭。实战案例:代理模式用于延迟加载对象。明智地使用设计模式可充分利用其优势并最小化缺点。

Guice框架应用了多项设计模式,包括:单例模式:通过@Singleton注解确保类只有一个实例。工厂方法模式:通过@Provides注解创建工厂方法,在依赖注入时获取对象实例。策略模式:将算法封装成不同策略类,通过@Named注解指定具体策略。
