承接上篇php模式设计之 单例模式,(虽然好像关系不大)。今天讲述第二种基础的模式设计——工厂模式。
那么何为工厂模式?
从名字来看,似乎看不出什么端倪。工厂模式,和生产有关?还是和生产流程有关?难道还和工厂领导有关?和领导秘书有关?秘书... 好了不卖关子了,所谓工厂模式还真和生产有关。生产什么呢?生产出来的是一个实例对象。通过什么设备生产?通过一个工厂类生产。怎么生产呢?工厂类调用自身静态方法来生产对象实例。
工厂模式有一个关键的构造,根据一般原则命名为Factory的静态方法,然而这只是一种原则,虽然工厂方法可以任意命名这个静态还可以接受任意数据的参数,必须返回一个对象。
为什么要是用工厂模式?
很多没接触过工厂模式的人会不禁问,为啥我要费那么大的劲儿去构造工厂类去创建对象呢?不去套用那些易维护,可扩展之类的话,我们可以考虑这样一个简单的问题。如果项目中,我们通过一个类创建对象。在快完成或者已经完成,要扩展功能的时候,发现原来的类类名不是很合适或者发现类需要添加构造函数参数才能实现功能扩展。我靠!我都通过这个类创建了一大堆对象实例了啊,难道我还要一个一个去改不成?我们现在才感受到了“高内聚低耦合”的博大精深。没问题,工厂方法可以解决这个问题。
再考虑一下,我要连接数据库,在php里面就有好几种方法,mysql扩展,mysqli扩展,PDO扩展。我就是想要一个对象用来以后的操作,具体要哪个,视情况而定喽。既然你们都是连接数据库的操作,你们就应该拥有相同的功能,建立连接,查询,断开连接...(此处显示接口的重要性)。总而言之,这几种方法应该“团结一致,一致对外”。如何实现呢?利用工厂模式。
工厂模式如何实现?
相对于单例模式,上面我们提供了足够的信息,工厂类,工厂类里面的静态方法。静态方法里面new一下需要创建的对象实例就搞定了。当然至于考虑上面的第二个问题,根据工厂类静态方法的参数,我们简单做个判断就好了。管你用if..else..还是switch..case..,能快速高效完成判断该创建哪个类的工作就好了。最后,一定要记得,工厂类静态方法返回一个对象。不是两个,更不是三个。
基本的工厂类:
<span>//</span><span>要创建对象实例的类</span> <span>class</span><span> MyObject{ } </span><span>//</span><span>工厂类</span> <span>class</span><span> MyFactory{ </span><span>public</span> <span>static</span> <span>function</span><span> factory(){ </span><span>return</span> <span>new</span> MyObject():<span> } } </span><span>$instance</span>=MyFactory::factory();
一个稍微复杂的工厂模式:
<?<span>php </span><span>interface</span><span> Transport{ </span><span>public</span> <span>function</span><span> go(); } </span><span>class</span> Bus <span>implements</span><span> Transport{ </span><span>public</span> <span>function</span><span> go(){ </span><span>echo</span> "bus每一站都要停"<span>; } } </span><span>class</span> Car <span>implements</span><span> Transport{ </span><span>public</span> <span>function</span><span> go(){ </span><span>echo</span> "car跑的飞快"<span>; } } </span><span>class</span> Bike <span>implements</span><span> Transport{ </span><span>public</span> <span>function</span><span> go(){ </span><span>echo</span> "bike比较慢"<span>; } } </span><span>class</span><span> transFactory{ </span><span>public</span> <span>static</span> <span>function</span> factory(<span>$transport</span><span>) { </span><span>switch</span> (<span>$transport</span><span>) { </span><span>case</span> 'bus': <span>return</span> <span>new</span><span> Bus(); </span><span>break</span><span>; </span><span>case</span> 'car': <span>return</span> <span>new</span><span> Car(); </span><span>break</span><span>; </span><span>case</span> 'bike': <span>return</span> <span>new</span><span> Bike(); </span><span>break</span><span>; } } } </span><span>$transport</span>=transFactory::factory('car'<span>); </span><span>$transport</span>->go();
需要工厂静态方法为factory()的时候,千万别再傻乎乎的把工厂类命名为Factory了。为啥啊?别忘了同名构造函数的事儿啊~
最后还是谈点感受吧,很多新手比较眼高手低,刚刚会了if..else..,session,cookie就要来点高大上的了。与人交谈动辄可扩展性,可维护性之类云云,至于实例的话,就会一时语塞。有时候觉得,无论自己写代码还是和别人学习,都处于“众里寻他千百度”的时候,真正踏实学习后,蓦然回首,“那人却在灯火阑珊处”,大呼:“原来这TM就是***啊”。
笔者不敢承认自己会模式设计,我也是个不足一年的初学者,分享博客只是想记录自己的学习历程,能得到知道更是求之不得。如果能给别人带来帮助,那就更好啦~~~
系列文章:
php模式设计之 单例模式
php模式设计之 工厂模式
php模式设计之 注册树模式