欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP設(shè)計(jì)模式之工廠模式(Factory Pattern)的講解

 更新時(shí)間:2019年03月21日 14:07:30   作者:CODETC  
今天小編就為大家分享一篇關(guān)于PHP設(shè)計(jì)模式之工廠模式(Factory Pattern)的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧

面向?qū)ο缶幊讨?,工廠模式是我們最常用的實(shí)例化對(duì)象模式,工廠類就是一個(gè)專門用來創(chuàng)建其它對(duì)象的類,工廠類在多態(tài)性編程實(shí)踐中是非常重要的。它允許動(dòng)態(tài)替換類,修改配置,會(huì)使應(yīng)用程序更加靈活。掌握工廠模式對(duì)Web開發(fā)是必不可少的,它會(huì)給你的系統(tǒng)帶來更大的可擴(kuò)展性和盡量少的修改量。

工廠模式通常用來返回類似接口的不同的類,工廠的一種常見用法就是創(chuàng)建多態(tài)的提供者。

通常工廠模式有一個(gè)關(guān)鍵的構(gòu)造,即一般被命名為factory的靜態(tài)方法。這個(gè)靜態(tài)方法可以接受任意數(shù)量的參數(shù),并且必須返回一個(gè)對(duì)象。

一個(gè)非常貼近生活的例子來告訴你什么是工廠模式

但是工廠模式真的是個(gè)累贅嗎?其實(shí)并不是!他能夠作為一種設(shè)計(jì)模式流傳至今,一定是有他的道理的!只不過我們看到的例子只能說明工廠模式是什么,并不能很好說明工廠模式的優(yōu)點(diǎn),所以我們學(xué)會(huì)后并不知道為什么要使用工廠模式,以及什么時(shí)候應(yīng)該去使用工廠模式!

其實(shí)工廠模式在我們的現(xiàn)實(shí)生活中非常常見,下面我舉個(gè)生活中的例子,大家應(yīng)該就能明白工廠模式的用處在哪里了!

麥當(dāng)勞大家都吃過吧?我們?nèi)c(diǎn)餐的時(shí)候,我們可以點(diǎn)一個(gè)漢堡,一杯可樂,一個(gè)薯?xiàng)l。我們還可以點(diǎn)一杯可樂,一個(gè)薯?xiàng)l。點(diǎn)完之后點(diǎn)餐員會(huì)問我們一句還要?jiǎng)e的嗎?你說不要了! 然后你的這一份餐就點(diǎn)完了,可以給錢了。咦,我們發(fā)現(xiàn)這是一個(gè)建造者模式(Builder Pattern)??!

(ps:這確實(shí)是突然發(fā)現(xiàn)的,之前寫建造者模式那篇文章的時(shí)候并沒有想到這個(gè)例子)

基本的工廠類:

<?php
 class Fruit {
 // 對(duì)象從工廠類返回
 }
 Class FruitFactory {
 public static function factory() {
  // 返回對(duì)象的一個(gè)新實(shí)例
  return new Fruit();
 }
 }
 // 調(diào)用工廠
 $instance = FruitFactory::factory();
?>

利用工廠類生產(chǎn)對(duì)象:

<?php
class Example
{
  // The parameterized factory method
  public static function factory($type)
  {
    if (include_once 'Drivers/' . $type . '.php') {
      $classname = 'Driver_' . $type;
      return new $classname;
    } else {
      throw new Exception('Driver not found');
    }
  }
}
// Load a MySQL Driver
$mysql = Example::factory('MySQL');
// Load an SQLite Driver
$sqlite = Example::factory('SQLite');
?>

一個(gè)完整的工廠類:

下面的程序定義了一個(gè)通用的工廠類,它生產(chǎn)能夠保存你所有操作的空對(duì)象,你可以獲得一個(gè)實(shí)例,這些操作都在那個(gè)實(shí)例中了。

<?php
  /**
   * Generic Factory class
   * This Factory will remember all operations you perform on it,
   * and apply them to the object it instantiates.
   */
  class FruitFactory {
    private $history, $class, $constructor_args;
    /**
     * Create a factory of given class. Accepts extra arguments to be passed to
     * class constructor.
     */
    function __construct( $class ) {
      $args = func_get_args();
      $this->class = $class;
      $this->constructor_args = array_slice( $args, 1 );
    }
    function __call( $method, $args ) {
      $this->history[] = array(
        'action'  => 'call',
        'method'  => $method,
        'args'  => $args
      );
    }
    function __set( $property, $value ) {
      $this->history[] = array(
        'action'  => 'set',
        'property'  => $property,
        'value'    => $value
      );
    }
    /**
     * Creates an instance and performs all operations that were done on this MagicFactory
     */
    function instance() {
      # use Reflection to create a new instance, using the $args 
      $reflection_object = new ReflectionClass( $this->class ); 
      $object = $reflection_object->newInstanceArgs( $this->constructor_args ); 
      # Alternative method that doesn't use ReflectionClass, but doesn't support variable
      # number of constructor parameters.
      //$object = new $this->class();
      # Repeat all remembered operations, apply to new object.
      foreach( $this->history as $item ) {
        if( $item['action'] == 'call' ) {
          call_user_func_array( array( $object, $item['method'] ), $item['args'] );
        }
        if( $item['action'] == 'set' ) {
          $object->{$item['property']} = $item['value'];
        }
      }
      # Done
      return $object;
    }
  }
  class Fruit {
    private $name, $color;
    public $price;
    function __construct( $name, $color ) {
      $this->name = $name;
      $this->color = $color;
    }
    function setName( $name ) {
      $this->name = $name;
    }
    function introduce() {
      print "Hello, this is an {$this->name} {$this->sirname}, its price is {$this->price} RMB.";
    }
  }
  # Setup a factory
  $fruit_factory = new FruitFactory('Fruit', 'Apple', 'Gonn');
  $fruit_factory->setName('Apple');
  $fruit_factory->price = 2;
  # Get an instance
  $apple = $fruit_factory->instance();
  $apple->introduce();
?>

工廠模式主要是為創(chuàng)建對(duì)象提供過渡接口,以便將創(chuàng)建對(duì)象的具體過程屏蔽隔離起來,達(dá)到提高靈活性的目的。

工廠模式可以分為三類:

  • 簡單工廠模式(Simple Factory)
  • 工廠方法模式(Factory Method)
  • 抽象工廠模式(Abstract Factory)

這三種模式從上到下逐步抽象,并且更具一般性。

簡單工廠模式又稱靜態(tài)工廠方法模式;從命名上就可以看出這個(gè)模式一定很簡單。它存在的目的很簡單:定義一個(gè)用于創(chuàng)建對(duì)象的接口。

工廠方法模式去掉了簡單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承。這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔(dān)。

工廠方法模式仿佛已經(jīng)很完美的對(duì)對(duì)象的創(chuàng)建進(jìn)行了包裝,使得客戶程序中僅僅處理抽象產(chǎn)品角色提供的接口。那我們是否一定要在代碼中遍布工廠呢?大可不必。也許在下面情況下你可以考慮使用工廠方法模式:

  • 當(dāng)客戶程序不需要知道要使用對(duì)象的創(chuàng)建過程。
  • 客戶程序使用的對(duì)象存在變動(dòng)的可能,或者根本就不知道使用哪一個(gè)具體的對(duì)象。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • php時(shí)區(qū)轉(zhuǎn)換轉(zhuǎn)換函數(shù)

    php時(shí)區(qū)轉(zhuǎn)換轉(zhuǎn)換函數(shù)

    godaddy主機(jī)在國外。把站點(diǎn)建站國外,顯示時(shí)間時(shí)可能需要時(shí)區(qū)轉(zhuǎn)換,下面是個(gè)方便的工具函數(shù),用于時(shí)區(qū)轉(zhuǎn)換
    2014-01-01
  • php瀏覽歷史記錄的方法

    php瀏覽歷史記錄的方法

    這篇文章主要介紹了php瀏覽歷史記錄的方法,涉及php操作cookie的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 關(guān)于php循環(huán)跳出的問題

    關(guān)于php循環(huán)跳出的問題

    本篇文章是對(duì)php中循環(huán)跳出的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • PHP array_shift()用法實(shí)例分析

    PHP array_shift()用法實(shí)例分析

    這篇文章主要介紹了PHP array_shift()用法,結(jié)合實(shí)例形式分析了array_shift()的功能、使用方法、相關(guān)問題與解決方法,需要的朋友可以參考下
    2019-01-01
  • docker?中搭建php環(huán)境經(jīng)驗(yàn)分享

    docker?中搭建php環(huán)境經(jīng)驗(yàn)分享

    這篇文章主要介紹了docker?中搭建php環(huán)境經(jīng)驗(yàn)分享的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • php數(shù)組索引與鍵值操作技巧實(shí)例分析

    php數(shù)組索引與鍵值操作技巧實(shí)例分析

    這篇文章主要介紹了php數(shù)組索引與鍵值操作技巧,涉及php數(shù)組的遍歷與索引、鍵值操作的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • 分享3個(gè)php獲取日歷的函數(shù)

    分享3個(gè)php獲取日歷的函數(shù)

    本文給大家匯總了3個(gè)php獲取日歷的函數(shù),分別是php獲取指定日期的月份的日歷、獲取指定日期所在月的開始日期與結(jié)束日期、獲取當(dāng)前星期的日期范圍,都是比較常用的方法,有需要的小伙伴可以參考下。
    2015-09-09
  • php解決crontab定時(shí)任務(wù)不能寫入文件問題的方法分析

    php解決crontab定時(shí)任務(wù)不能寫入文件問題的方法分析

    這篇文章主要介紹了php解決crontab定時(shí)任務(wù)不能寫入文件問題的方法,結(jié)合實(shí)例形式分析了crontab定時(shí)任務(wù)無法正常執(zhí)行的原因與解決方法,需要的朋友可以參考下
    2019-09-09
  • PHP基于SPL實(shí)現(xiàn)的迭代器模式示例

    PHP基于SPL實(shí)現(xiàn)的迭代器模式示例

    這篇文章主要介紹了PHP基于SPL實(shí)現(xiàn)的迭代器模式,簡單描述了迭代器模式的概念、原理并結(jié)合實(shí)例形式分析了php使用SPL實(shí)現(xiàn)迭代器模式的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-04-04
  • thinkphp autoload 命名空間自定義 namespace

    thinkphp autoload 命名空間自定義 namespace

    這篇文章主要介紹了thinkphp autoload 命名空間自定義 namespace的相關(guān)資料,需要的朋友可以參考下
    2015-07-07

最新評(píng)論