今天小编就为大家分享一篇关于PHP设计模式之工厂模式(Factory Pattern)的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

面向对象编程中,工厂模式是我们最常用的实例化对象模式,工厂类就是一个专门用来创建其它对象的类,工厂类在多态性编程实践中是非常重要的。它允许动态替换类,修改配置,会使应用程序更加灵活。工厂模式对Web开发是必不可少的,它会给你的系统带来更大的可扩展性和尽量少的修改量。

工厂模式通常用来返回类似接口的不同的类,工厂的一种常见用法就是创建多态的提供者。

通常工厂模式有一个关键的构造,即一般被命名为factory的静态方法。这个静态方法可以接受任意数量的参数,并且必须返回一个对象。

一个非常贴近生活的例子来告诉你什么是工厂模式

但是工厂模式真的是个累赘吗?其实并不是!他能够作为一种设计模式流传至今,一定是有他的道理的!只不过我们看到的例子只能说明工厂模式是什么,并不能很好说明工厂模式的优点,所以我们学会后并不知道为什么要使用工厂模式,以及什么时候应该去使用工厂模式!

其实工厂模式在我们的现实生活中非常常见,下面我举个生活中的例子,大家应该就能明白工厂模式的用处在哪里了!

麦当劳大家都吃过吧?我们去点餐的时候,我们可以点一个汉堡,一杯可乐,一个薯条。我们还可以点一杯可乐,一个薯条。点完之后点餐员会问我们一句还要别的吗?你说不要了! 然后你的这一份餐就点完了,可以给钱了。咦,我们发现这是一个建造者模式(Builder Pattern)啊!

(ps:这确实是突然发现的,之前写建造者模式那篇文章的时候并没有想到这个例子)

基本的工厂类:

<?php
 class Fruit {
 // 对象从工厂类返回
 }
 Class FruitFactory {
 public static function factory() {
  // 返回对象的一个新实例
  return new Fruit();
 }
 }
 // 调用工厂
 $instance = FruitFactory::factory();
?>

利用工厂类生产对象:

<?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');
?>

一个完整的工厂类:

下面的程序定义了一个通用的工厂类,它生产能够保存你所有操作的空对象,你可以获得一个实例,这些操作都在那个实例中了。

<?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();
?>

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

工厂模式可以分为三类:

    简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。

简单工厂模式又称静态工厂方法模式;从命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口。那我们是否一定要在代码中遍布工厂呢?大可不必。也许在下面情况下你可以考虑使用工厂方法模式:

    当客户程序不需要知道要使用对象的创建过程。 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对爱安网的支持。如果你想了解更多相关内容请查看下面相关链接

最新资讯
台积电宣布将建全球首家2nm工厂 最快2024年投产

台积电宣布将建全球首

台积电正式宣布启动2nm工艺的研发,这使其成为第一家宣
8月快递经营数据:顺丰营收破90亿 圆通单票收入最低

8月快递经营数据:顺丰

顺丰控股、圆通速递、申通快递、韵达快递(下称顺丰、圆
"一键换脸"之后是"剪刀手" 网络安全召唤AI反制高手

"一键换脸"之后是"

“V字”手势或“剪刀手”诞生以来风靡全球,已成为人们
失速的共享办公:WeWork上市遇阻 戳破行业盈利泡沫

失速的共享办公:WeWork

“从现在开始,大家要勒紧裤腰带过日子了。”
华为放大招 布局计算黄金十年

华为放大招 布局计算

仍处在“实体清单”中的华为首次提出计算战略。自救需
苹果:新iPhone核心部件将使用回收稀土

苹果:新iPhone核心部件

苹果公司今日表示,新一代iPhone的核心零部件Taptic Eng
最新文章
浅谈PHP SHA1withRSA加密生成签名及验签

浅谈PHP SHA1withRSA

这篇文章主要介绍了PHP SHA1withRSA加密生成签名及验
PHP实现对数字分隔加千分号的方法

PHP实现对数字分隔加

今天小编就为大家分享一篇关于PHP实现对数字分隔加千
PHP生成指定范围内的N个不重复的随机数

PHP生成指定范围内的N

今天小编就为大家分享一篇关于PHP生成指定范围内的N个
PHP实现的数据对象映射模式详解

PHP实现的数据对象映

这篇文章主要介绍了PHP实现的数据对象映射模式,结合实
使用ucenter实现多站点同步登录的讲解

使用ucenter实现多站

今天小编就为大家分享一篇关于使用ucenter实现多站点
PHP中单例模式的使用场景与使用方法讲解

PHP中单例模式的使用

今天小编就为大家分享一篇关于PHP中单例模式的使用场