工厂模式

  1. 概念

    工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。

  2. 好处

    使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需要更改该工厂方法内容即可,不需要逐一寻找代码中具体实例化的地方(new 处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。

  3. 分类

    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
  • 简单工厂模式

    简单工厂模式又称静态工厂模式,之所以可以这么说,是因为简单工厂模式是通过一个静态方法来创建对象的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <?php
    class DbMysql
    {
    public function conn()
    {
    echo "连接MySQL";
    }
    }

    class DbSqlite
    {
    public function conn()
    {
    echo "连接SQLite";
    }
    }

    class DbFactory
    {
    public static function createIns($type)
    {
    switch ($type)
    {
    case 'mysql':
    return DbMysql();
    break;
    case 'sqlite':
    return new DbSqlite();
    break;
    default:
    throw new ErrorException('类型错误');
    }

    }
    }

    $mysql = DbFactory::createIns('mysql');
    $mysql->conn();

    $sqlite = DbFactory::createIns('sqlite');
    $sqlite->conn();

  • 工厂方法模式

    简单工厂模式实现了产品类的代码跟客户端代码的分离,但会有一个问题,优秀的代码是符合“开闭原则”如果你要加一个C类产品,你就要修改工厂类里面的代码,也就是说要增加条件语句如:switch–case。对于这个问题,接下来的工厂方法模式可以解决这个问题。

    1. 概念

      工厂方法就是为配一个产品提供一个独立的工厂类,通过不同的工厂实例来创建不同的产品实例。

    2. 优点

      • 拥有良好的封装性,代码结构清晰,对于每一个对象的创建都是有条件约束的。如:调用一个具体的产品对象,只需要知道这个产品的类名和约束参数就可以了,不用知道创建对象自身的复杂过程。降低模块之间的耦合度。
      • 拥有良好的扩展性,新增一个产品类,只需要适当的增加工厂类或者扩展一个工厂类,如下面的例子中,当需要增加一个数据库Oracle的操作,则只需要增加一个Oracle类,工厂类不用修改任务就可完成系统扩展。
      • 屏蔽产品类,这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。
    3. 使用场景

      • 支付宝、微信、银联的连接方式(connectMode),支付方式(payMode)。使用工厂模式,“客户”就不需要知道具体的链接方式和支付方式了,只需要调用connectMode和payMode即可。
      • MySQL、SQL Server、Oracle等数据库的连接方式(connectMode)、查询方式(selectMode)等操作可以使用工厂模式进行封装。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      <?php
      //数据库操作接口
      interface Db
      {
      public function conn();
      }

      class DbMysql implements Db
      {
      public function conn()
      {
      echo "链接MySQL";
      }
      }

      class DbSqlite implements Db
      {
      public function conn()
      {
      echo "连接SQLite";
      }
      }

      //工厂接口
      interface Factory
      {
      public static function createIns();
      }

      class MysqlFactory implements Factory
      {
      public static function createIns()
      {
      return new DbMysql();
      }
      }

      class SqliteFactory implements Factory
      {
      public static function createIns()
      {
      return new DbSqlite();
      }
      }

      //客户端
      $mysql = MysqlFactory::createIns();
      $mysql->conn();
      $sqlite = SqliteFactory::createIns();
      $sqlite->conn();
  • 抽象工厂模式

    1. 概念

      抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象,而且使用抽象工厂模式还要满足以下条件:

      • 系统中有多个产品族,而系统一次只可能消费其中一族产品
      • 同属于同一产品族的产品可以使用
      • 产品族:位于不同产品等级结构中,功能相关联的产品组成的家族。下面例子的汽车和空调就是两个产品树,奔驰C200+格力某型号空调就是一个产品族,同理,奥迪A4+海尔某型号空调也是一个产品族。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      <?php
      //汽车(抽象产品接口)
      interface AutoProduct
      {
      public function dirve();
      }

      class AudiA4Product implements AutoProduct
      {
      public function dirve()
      {
      echo '奥迪A4';
      }
      }

      class BenzC200Product implements AutoProduct
      {
      public function dirve()
      {
      echo '奔驰C200';
      }
      }

      //空调(抽象产品接口)
      interface AirCondition
      {
      public function blow();
      }

      class GreeAirCondition implements AirCondition
      {
      public function blow()
      {
      echo '格力';
      }
      }

      class HaierAirCondition implements AirCondition
      {
      public function blow()
      {
      echo '海尔';
      }
      }

      //工厂接口
      interface Factory
      {
      public static function getAuto();
      public static function getAirCondition();
      }

      //工厂A 奥迪A4+海尔空调
      class AFactory implements Factory
      {
      public static function getAuto()
      {
      return new AudiA4Product();
      }
      public static function getAirCondition()
      {
      return new HaierAirCondition();
      }
      }

      //工厂B 奔驰+格力
      class BFactory implements Factory
      {
      public static function getAuto()
      {
      return new BenzC200Product();
      }
      public static function getAirCondition()
      {
      return new GreeAirCondition();
      }
      }

      //客户端
      //A工厂制作车
      $auto_carA = AFactory::getAuto();
      $auto_airA = AFactory::getAirCondition();

      //奥迪+空调
      $auto_carA->dirve();
      $auto_airA->blow();
  • 三种工厂模式的比较

    • 简单工厂:用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
    • 工厂方法:用来生产同一等级结构中的固定产品。(支持增加任意产品)
    • 抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)