当前位置: 首页 > 后端技术 > PHP

php的三种主要设计模式

时间:2023-03-29 19:09:55 PHP

(非原创)1、什么是单例模式设计?初学者一开始会被这个高大上的名字吓倒。对于有丰富编程经验的老手来说,模式设计无处不在。许多联系人框架都是基于各种模式设计的。简单的说,在写代码的过程中,最开始接触的往往是面向过程的、简单的、基础的编程。这时候我们往往追求的是代码能够实现一定的功能就万事大吉了。代码再冗余,代码是否可重用,效率再高,只要能实现功能即可。但是,真正应用在实践中,更被大家采用的是高效、可复用、方便团队开发的代码。基于这些因素,你不能像练手一样随便命名函数名和乱放脚本。模式设计告诉人们提供一种组织代码的思维方式,实现代码的可重用性,使代码更容易被他人理解,保证代码的可靠性。  在所有的模式设计中,都有三种基本的设计模式,单例模式、工厂模式、注册树模式,而其他模式往往都是基于这些模式,今天带来单例模式。  什么是单例模式?  根据这个名字,我们很容易理解单例模式是指整个应用程序中只有一个对象实例的设计模式。  为什么要用单例模式?  php经常和数据库打交道。如果在应用程序中频繁创建连接对象和执行新的操作,会消耗大量的系统内存资源,这不是我们希望看到的。再者,在团队合作的项目中,单例模式可以有效防止不同的程序员分别new自己的对象,造成人为的系统消耗。 如何构建单例模式?  看到这个问题,相信优秀的程序员很可能会根据需求尝试创建单例模式,而不是等待前人的经验。不像其他博主告诉你什么样的模式是单例模式,我更愿意和有面向对象编程基础经验的你一起考虑如何自己构建单例模式。  先进入正题,单例模式是一种只有一个对象实例的设计模式。这是非常痛苦的。我们平时创建的类要么可以创建很多对象,要么不能创建对象(抽象类)。创建一个对象,需要一个类,不能是抽象类。这个类防止其他人多次创建函数。我们很自然地考虑从构造器入手。但是,每次new操作都会调用构造函数,即会多次创建对象实例。这有悖于我们最初的设计意图。一定要在这里将构造函数声明为private或者protected来解决这个问题。  构造函数被声明为private或者protected,所以注定不会通过new方法创建实例对象。而且我们发现,经过这一步,解决问题的前景变得更加清晰。为什么?由于无法通过new方法创建对象实例,我们只能通过类内部的方法来创建对象实例。此时我们面临着一个有趣的鸡生蛋还是蛋生鸡的问题。我们往往在对象创建之后调用对象的方法,这时候就需要调用类中的方法来创建对象。毫无疑问,无论对象是否创建都可以调用的方法的解决方案是使用关键字--static。  在类中创建静态方法做了什么工作?回到主题:确保只创建一个实例对象。如何确保只有一个?这个很简单,如果判断一下。存在则直接返回,不存在则自己创建。当然,这个实例对象是类的静态属性。至此,单例模式所需的功能已经实现。真的完了吗?不算~如果有类继承这个类,把构造函数声明为public不是坏事吗?需要在构造方法前加上final关键字。  最后贴上单例模式代码,代码解释如上~~hash=rand(1,9999);}staticpublicfunctiongetInstance(){if(self::$insinstanceofself){returnself::$ins;}self::$ins=newself();返回自我::$ins;}}单例模式本身并不复杂,但需要深入理解。很多初学者还是感叹:卧槽,构造方法不总是public的~卧槽,不用new也能创建对象~其实作者想说的是无论构造方法声明为public,private还是protected,对象最后将被创建,每次都会被调用。一直都是用new来创建对象实例,单例模式也是用new来创建对象,只是换了一个地方,从类外到类内。2.工厂模式那么什么是工厂模式呢?  看名字好像没什么头绪。工厂模式,跟生产有关?还是跟制作过程有关?还跟厂领导有关吗?跟领导书记有关系吗?书记……嗯,不瞒你说,所谓的工厂模式,还真是跟生产有关。生产什么?产生的是一个实例对象。用什么设备生产的?通过工厂类生产。如何生产?工厂类调用它自己的静态方法来产生对象实例。 工厂模式有一个关键的结构,按照一般原则命名为Factory的静态方法。然而,这只是一个原则。虽然工厂方法可以任意命名,但是thisstatic也可以接受任意数据的参数,而且必须返回一个对象。  为什么要使用工厂模式?  很多没有接触过工厂模式的人不禁要问,为什么我要花那么多心思去构造工厂类来创建对象呢?与其套用易维护、可扩展性等词,不如考虑这样一个简单的问题。如果在项目中,我们通过一个类来创建对象。当快完成或者已经完成的时候,要扩展功能的时候,发现原来的类名不太合适或者发现类需要添加构造函数参数来实现功能扩展。我靠!我通过这个类创建了很多对象实例,是否要一一更改?我们现在才感受到“高内聚低耦合”的深刻。没问题,工厂方法可以解决这个问题。  又想了想,想连接数据库,php里面有几种方法,mysql扩展,mysqli扩展,PDO扩展。我只是想要一个对象,用于以后的操作,具体要哪个看情况。既然你们都是连接数据库的操作,那么你们的功能应该是一样的,建立连接,查询,断开……(这里说明接口的重要性)。总而言之,这些方法应该是“统一开放”的。如何?使用工厂模式。  工厂模式是如何实现的?  相对于单例模式,我们上面已经提供了足够的信息,工厂类,以及工厂类中的静态方法。在静态方法中,只需new需要创建的对象实例即可。当然,对于上面的第二个问题,我们可以简单的根据工厂类的静态方法的参数来判断。无论是使用if..else..还是switch..case..,如果能快速高效的完成判断创建哪个类的工作就好了。最后,记住工厂类静态方法返回一个对象很重要。不是两个,更不用说三个了。基本工厂类//classclassMyObject{}创建对象实例//factoryclassclassMyFactory{publicstaticfunctionfactory(){returnnewMyObject():}}$instance=MyFactory::factory();稍微复杂一点Pointfactoryclass去();当要求工厂的静态方法为factory()时,不要傻傻的把工厂类命名为Factory。为什么?别忘了同名的构造函数~  最后说说一些感受吧。很多新手比较聪明,刚学了if..else..、session、cookies。与人交谈易于扩展、可维护性等。至于例子,我就一时无语了。有时候觉得无论自己写代码还是向别人学习,都处在“人山人海找他千百度”的时代。没错”。3.注册树模式什么是注册树模式?  注册树模式当然也叫注册模式,注册商模式。我之所以在这里矫情它的名字,是因为我觉得这个名字注册树的模式更容易让人理解,和前两篇文章一样,我们的文章还是从名字开始,注册树模式是一种将对象实例注册到一个全局对象树中,并在调用时从对象树中挑选出来的模式设计方法需要。这让我想起小时候买糖葫芦的时候,卖糖葫芦的会把糖葫芦粘在一根大杆子上,人家买的时候会摘下来。不同的是注册树模式还是会的摘下来就在,可以摘很多次,但是摘一次糖葫芦就没有了。。。。  为什么要用注册树模型?  单例模式解决了怎么办的问题到在整个项目中创建唯一的对象实例,工厂模式解决了不用new怎么创建实例对象的方法。那么注册树模型要解决什么问题呢?在考虑这个问题之前,我们还需要考虑前两种模式目前所面临的局限性。首先,单例模式创建唯一对象的过程本身就有一个判断,即判断对象是否存在。如果存在,则返回对象,如果不存在,则创建对象并返回。每次创建实例对象时都有这样一层判断。工厂模式更关心延期维护的问题。总的来说,单例模式和工厂模式可以生产出更合理的对象。如何方便地调用这些对象呢?而且在项目中这样建立的对象就像散兵游勇,不方便统筹管理和安排。因此,注册树模式应运而生。不管你是通过单例模式、工厂模式,还是两者结合的方式生成对象,都会给我“插入”到注册树中。当我使用对象时,直接从注册树中取出即可。这和我们使用全局变量一样方便实用。并且注册树模式也为其他模式提供了一个很好的思路。  如何实现注册树?  通过上面的描述,我们似乎很容易就找到了解决办法。首先我们需要一个类作为注册树,这是毫无疑问的。所有对象都“插入”到注册树中。此注册表树应由静态变量提供服务。而这个注册树应该是一个二维数组。这个类应该有一个插入对象实例的方法(set()),以及一个相应的撤销对象实例的方法(_unset())。当然,最重要的是需要有一个读取对象的方法(get())。有了这些,我们就可以愉快的完成注册树模式了~~~  我们来做一个三种模式的小组合吧。简单的创建一个实例对象远没有这么复杂,但是如果在大型项目中使用,其方便性不言而喻。hash=rand(1,9999);}staticpublicfunctiongetInstance(){if(self::$insinstanceofself){returnself::$ins;}self::$ins=newself();返回自我::$ins;}}//工厂模式classRandFactory{publicstaticfunctionfactory(){returnSingle::getInstance();}}//注册树类Register{protectedstatic$objects;publicstaticfunctionset($alias,$object){self::$objects[$alias]=$object;}publicstaticfunctionget($alias){returnself::$objects[$alias];}publicstaticfunction_unset($alias){unset(self::$objects[$alias]);}}Register::set('rand',RandFactory::factory());$object=Register::get('rand');print_r($object);至此,三种模式设计介绍完毕。各种图案设计将相互补充。后面介绍其他模式时,或多或少会用到一种或多种其他设计模式。  不懂一个模型也没关系。相信深入编程一定会产生惊喜感。希望你和我一起进步。