首頁 >後端開發 >php教程 >php設計模式基礎知識與應用

php設計模式基礎知識與應用

墨辰丷
墨辰丷原創
2018-06-07 13:57:581237瀏覽

這篇文章主要介紹php設計模式基礎與應用,有興趣的朋友參考下,希望對大家有幫助。

php註冊樹模式

什麼是註冊樹模式?

  註冊樹模式當然也叫註冊模式,註冊器模式。之所以我在這裡矯情一下它的名稱,是因為我感覺註冊樹這個名稱更容易讓人理解。像前兩篇一樣,我們這篇依舊是從名字入手。註冊樹模式透過將物件實例註冊到一棵全域的物件樹上,需要的時候從物件樹上採摘的模式設計方法。   這讓我想起了小時候買糖葫蘆,賣糖葫蘆的將糖葫蘆插在一個大的桿子上,人們買的時候就取下來。不同的是,註冊樹模式摘下來還會有,能摘很多次,糖葫蘆摘一次就沒了。 。 。

為什麼要採用註冊樹模式?

  單例模式解決的是如何在整個專案中建立唯一物件實例的問題,工廠模式解決的是如何不透過new建立實例物件的方法。那麼註冊樹模式想解決什麼問題呢?在考慮這個問題前,我們還是有必要考慮下前兩種模式目前面臨的限制。  首先,單例模式創造唯一物件的過程本身還有一種判斷,就是判斷物件是否存在。存在則傳回對象,不存在則建立對象並返回。每次創建實例物件都要存在這麼一層判斷。工廠模式更多考慮的是擴展維護的問題。總的來說,單例模式和工廠模式可以產生更合理的物件。怎麼方便呼叫這些物件呢?而且在專案內如此建立的對象好像散兵游勇一樣,不便統籌管理安排啊。因而,註冊樹模式應運而生。不管你是透過單例模式還是工廠模式還是二者結合產生的對象,都統統給我「插到」註冊樹上。我用某個物件的時候,直接從註冊樹上取一下就好。這和我們使用全域變數一樣的方便實用。而且註冊樹模式也為其他模式提供了一個非常好的想法。

如何實作註冊樹?

  透過上述的描述,我們似乎很容易就找到了解決方法。首先我們需要一個作為註冊樹的類,這毋庸置疑。所有的物件「插入」到註冊樹上。這個註冊樹應該由一個靜態變數來充當。而且這個註冊樹應該是一個二維數組。這個類別應該有一個插入物件實例的方法(set()),當讓相對應的就應該有一個撤銷物件實例的方法(_unset())。當然最重要的是還需要有一個讀取物件的方法(get())。擁有這些,我們就可以愉快地完成註冊樹模式啦~~~

  下面讓三種模式做個小小的結合。單純創建一個實例物件遠遠沒有這麼複雜,但運用於大型專案的話,便利性便不言而喻了。

<?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(&#39;rand&#39;,RandFactory::factory());
$object=Register::get(&#39;rand&#39;);
print_r($object);

       至此,以三種模式設計介紹完成。各種模式設計本身就會相輔相成,往後介紹其他模式的時候,多多少少會用到一種或多種其他設計模式。

     一種模式不懂不要緊,相信程式設計的深入,定會產生恍然大悟的驚喜感 ,願諸君與我共進步。

php工廠模式

那麼何為工廠模式?

  從名字來看,似乎看不出什麼端倪。工廠模式,和生產有關?還是跟生產流程有關?難道還和工廠領導有關?和領導秘書有關?秘書...     好了不賣關子了,所謂工廠模式還真和生產有關。生產什麼呢?生產出來的是一個實例物件。透過什麼設備生產?透過一個工廠類生產。怎麼生產呢?工廠類別呼叫自身靜態方法來生產物件實例。

   工廠模式有一個關鍵的構造,根據一般原則命名為Factory的靜態方法,然而這只是一種原則,雖然工廠方法可以任意命名這個靜態還可以接受任意數據的參數,必須返回一個對象。

為什麼要用工廠模式?

  很多沒接觸過工廠模式的人會不禁問,為啥我要費那麼大的勁兒去構造工廠類去創建對象呢?不去套用那些容易維護,可擴充之類的話,我們可以考慮這樣一個簡單的問題。如果在專案中,我們透過一個類別建立物件。在快完成或已經完成,要擴展功能的時候,發現原來的類別類別名稱不是很合適或發現類別需要添加建構函數參數才能實現功能擴展。我靠!我都透過這個類別創建了一大堆物件實例了啊,難道我還要一個一個去改不成?我們現在才感受到了「高內聚低耦合」的博大精深。沒問題,工廠方法可以解決這個問題。

  再考虑一下,我要连接数据库,在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 &#39;bus&#39;:
    return new Bus();
    break;
   case &#39;car&#39;:
    return new Car();
    break;
   case &#39;bike&#39;:
    return new Bike();
    break;
  }
 }
}
$transport=transFactory::factory(&#39;car&#39;);
$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;
 } 
}

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

PHP实现自动发送邮件功能代码(qq 邮箱)_php实例

php实现追加内容到txt文件中的方法

PHP无限循环获取MySQL数据

以上是php設計模式基礎知識與應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn