Home >Backend Development >PHP Tutorial >A complete collection of PHP basic design patterns (registration tree mode, factory mode, single column mode), design pattern single column_PHP tutorial
No more nonsense, let me first introduce the registration tree mode to you and then introduce it Factory mode finally introduces single-column mode to you. This article is written in great detail. Let’s learn together.
php registration tree mode
What is registration tree mode?
Of course, the registration tree mode is also called registration mode and registrar mode. The reason why I am pretentious about its name here is because I feel that the name registration tree is easier for people to understand. Like the previous two articles, our article still starts with the name. The registration tree pattern is a pattern design method that registers object instances to a global object tree and picks from the object tree when needed. This reminds me of buying candied haws on a stick when I was a kid. The candied haws seller would stick the candied haws on a big pole and people would take them off when they bought them. The difference is that in the registration tree mode, there will still be some after being picked, and it can be picked many times, but the candied haws will be gone after being picked once. . .
Why use registration tree mode?
The singleton mode solves the problem of how to create a unique object instance in the entire project, and the factory mode solves the problem of how to create an instance object without using new. So what problem does the registration tree mode want to solve? Before considering this issue, we still need to consider the limitations currently faced by the first two models. First of all, the process of creating a unique object in the singleton mode itself also has a judgment, that is, whether the object exists. If it exists, the object is returned; if it does not exist, the object is created and returned. Every time an instance object is created, there must be such a layer of judgment. The factory model considers more the issue of extended maintenance. In general, the singleton pattern and factory pattern can produce more reasonable objects. How to conveniently call these objects? Moreover, the objects created in this way in the project are like scattered soldiers, making it inconvenient for overall management and arrangement. Therefore, the registration tree model came into being. Regardless of whether you generate objects through singleton mode, factory mode, or a combination of the two, they are all "inserted" into the registration tree. When I use an object, I just fetch it directly from the registration tree. This is as convenient and practical as using global variables. And the registration tree pattern also provides a very good idea for other patterns.
How to implement a registration tree?
Through the above description, we seem to have easily found a solution. First we need a class as a registration tree, of course. All objects are "inserted" into the registration tree. This registration tree should be served by a static variable. And this registration tree should be a two-dimensional array. This class should have a method for inserting object instances (set()), and correspondingly there should be a method for undoing object instances (_unset()). Of course, the most important thing is to have a method to read the object (get()). With these, we can happily complete the registration tree mode~~~
Now let’s make a small combination of the three modes. Simply creating an instance object is far less complicated, but when applied to large projects, the convenience is self-evident.
<?php //创建单例 class Single{ public $hash; static protected $ins=null; final protected function __construct(){ $this->hash=rand(1,9999); } static public function getInstance(){ if (self::$ins instanceof self) { return self::$ins; } self::$ins=new self(); return self::$ins; } } //工厂模式 class RandFactory{ public static function factory(){ return Single::getInstance(); } } //注册树 class Register{ protected static $objects; public static function set($alias,$object){ self::$objects[$alias]=$object; } public static function get($alias){ return self::$objects[$alias]; } public static function _unset($alias){ unset(self::$objects[$alias]); } } Register::set('rand',RandFactory::factory()); $object=Register::get('rand'); print_r($object);
At this point, the introduction of the three modes of design is completed. Various pattern designs themselves will complement each other. When introducing other patterns in the future, one or more other design patterns will be used more or less.
It doesn’t matter if you don’t understand a certain model. I believe that with the in-depth programming, there will be a surprise of sudden enlightenment. I hope you will make progress with me.
php factory mode
So what is factory mode?
Judging from the name, there seems to be no clue. Factory mode, related to production? Or is it related to the production process? Could it be related to the factory leaders? Is it related to the leadership secretary? Secretary... Okay, let’s not get too close. The so-called factory model is really related to production. What to produce? What is produced is an instance object. What equipment is used to produce it? Produced through a factory class. How to produce it? The factory class calls its own static methods to produce object instances.
The factory pattern has a key construct, which is a static method named Factory according to the general principle. However, this is just a principle. Although the factory method can be named arbitrarily, this static method can also accept parameters of any data and must return an object.
Why use factory mode?
很多没接触过工厂模式的人会不禁问,为啥我要费那么大的劲儿去构造工厂类去创建对象呢?不去套用那些易维护,可扩展之类的话,我们可以考虑这样一个简单的问题。如果项目中,我们通过一个类创建对象。在快完成或者已经完成,要扩展功能的时候,发现原来的类类名不是很合适或者发现类需要添加构造函数参数才能实现功能扩展。我靠!我都通过这个类创建了一大堆对象实例了啊,难道我还要一个一个去改不成?我们现在才感受到了“高内聚低耦合”的博大精深。没问题,工厂方法可以解决这个问题。
再考虑一下,我要连接数据库,在php里面就有好几种方法,mysql扩展,mysqli扩展,PDO扩展。我就是想要一个对象用来以后的操作,具体要哪个,视情况而定喽。既然你们都是连接数据库的操作,你们就应该拥有相同的功能,建立连接,查询,断开连接...(此处显示接口的重要性)。总而言之,这几种方法应该“团结一致,一致对外”。如何实现呢?利用工厂模式。
工厂模式如何实现?
相对于单例模式,上面我们提供了足够的信息,工厂类,工厂类里面的静态方法。静态方法里面new一下需要创建的对象实例就搞定了。当然至于考虑上面的第二个问题,根据工厂类静态方法的参数,我们简单做个判断就好了。管你用if..else..还是switch..case..,能快速高效完成判断该创建哪个类的工作就好了。最后,一定要记得,工厂类静态方法返回一个对象。不是两个,更不是三个。
基本的工厂类:
//要创建对象实例的类 class MyObject{ } //工厂类 class MyFactory{ public static function factory(){ return new MyObject(): } } $instance=MyFactory::factory();
一个稍微复杂的工厂模式:
<?php interface Transport{ public function go(); } class Bus implements Transport{ public function go(){ echo "bus每一站都要停"; } } class Car implements Transport{ public function go(){ echo "car跑的飞快"; } } class Bike implements Transport{ public function go(){ echo "bike比较慢"; } } class transFactory{ public static function factory($transport) { switch ($transport) { case 'bus': return new Bus(); break; case 'car': return new Car(); break; case 'bike': return new Bike(); break; } } } $transport=transFactory::factory('car'); $transport->go();
需要工厂静态方法为factory()的时候,千万别再傻乎乎的把工厂类命名为Factory了。为啥啊?别忘了同名构造函数的事儿啊~
最后还是谈点感受吧,很多新手比较眼高手低,刚刚会了if..else..,session,cookie就要来点高大上的了。与人交谈动辄可扩展性,可维护性之类云云,至于实例的话,就会一时语塞。有时候觉得,无论自己写代码还是和别人学习,都处于“众里寻他千百度”的时候,真正踏实学习后,蓦然回首,“那人却在灯火阑珊处”,大呼:“原来这TM就是***啊”。
笔者不敢承认自己会模式设计,我也是个不足一年的初学者,分享博客只是想记录自己的学习历程,能得到知道更是求之不得。如果能给别人带来帮助,那就更好啦~~~
php单列模式
模式设计是什么?
初学者一开始会被这高大上的名称给唬住。而对于有丰富编程经验的老鸟来说,模式设计又是无处不在。很多接触的框架就是基于各种模式设计形成的。 简单说,在写代码的过程中一开始往往接触的是面向过程的,简单的基础的编程。这个时候我们往往追求的是代码能够实现某项功能就万事大吉。管他代码多么冗余,管他代码是否可重用,管他效率如何,能实现功能就好。但是,真正应用于实际的,更被大家采纳的是那些高效的,可重用的,便于团队开发的代码。基于这些因素,你不能像练手一样,随便命名函数名,随便放置脚本。模式设计告诉是给人们组织代码提供一种思路,实现可重用代码、让代码更容易被他人理解、保证代码可靠性。
在所有模式设计中,有三种基础设计模式,单例模式,工厂模式,注册树模式,其他模式往往基于这几种模式,下面介绍的是单例模式。
什么是单例模式?
根据这个名称,我们很容易了解到,单例模式指的是在整个应用中只有一个对象实例的设计模式。
为什么要用单例模式?
php常常和数据库打交道,如果在应用中如果频繁建立连接对象,进行new操作的话,会消耗大料的系统内存资源,这并不是我们希望看到的。再则,在团队合作项目中,单例模式可以有效避免不同程序员new自己的对象,造成人为的系统消耗。
如何建立单例模式?
在看到这个问题的时候,相信优秀的程序员很可能自己试着根据要求去创建单例模式,而不是坐等前人的经验。区别于其他博友告诉你什么样的模式是单例模式,我人更愿意和有面向对象编程基本经验的你考虑一下如何自己建立单例模式。
我们首先从题目出发,单例模式是只有一个对象实例的设计模式。这一点是很让人蛋疼的。我们平常创建的类不是能创建很多对象的,就是不能创建对象的(抽象类)。要创建对象需要有类这是必须的,而且不能是抽象类。这个类要防止别人可以多次创建函数。我们自然而然考虑到了从构造函数入手。但是,每次new操作都会调用构造函数,也就是会多次创建对象实例。这和我们设计初衷相悖了。在此处务必申明构造函数为private或者protected这样才能解决这个问题。
构造函数被申明为private或者protected这注定无法通过new的方法创建实例对象了。而且我们发现,经过这一步处理后,解决问题的前景变得明朗起来?为什么呢?既然无法通过new方法创建对象实例,那么我们只能通过类内的方法来创建对象实例了。 这个时候我们面临一个有趣的先有鸡还是先有蛋的问题。我们往往往往是创建了对象后才调用对象的方法,而此时需要调用类里面的方法来创建对象。不受是否创建对象影响都能调用的方法的解决方案毋庸置疑那就是利用关键字--static。
在类内创建静态方法完成完成什么工作呢?回归主题:确保只创建一个实例对象。如何确保只有一个呢?这很简单,if判断一下啊。存在的话直接返回,不存在自己创建一个嘛。当然这个实例对象是类的静态属性。至此,单例模式要求的功能实现完成。真的完成了么?还不算~如果有个类继承本类,将构造方法申明为public那不又坏事儿了?那有必要在构造方法前加final关键字了。
最后贴上单例模式代码,代码解释都在上面了~~
<?php class Single{ public $hash; static protected $ins=null; final protected function __construct(){ $this->hash=rand(1,9999); } static public function getInstance(){ if (self::$ins instanceof self) { return self::$ins; } self::$ins=new self(); return self::$ins; } }
本身单例模式并不复杂,但需要深入理解。很多初学者依旧会感叹:卧槽,构造方法原来不一直是public啊~卧槽还可以不通过new创建对象啊~其实笔者想说,不管构造方法被申明为public,private还是protected,最终创建对象的时候都会调用。一直是new创建对象实例,单例模式也用new创建对象,只是换个地方而已,从类外到类内。
最后对研究出各种精妙的模式设计的程序员表示拜服~~