php设计模式之工厂模式

1. 工厂模式分类

工厂模式具体可分为三类模式:简单工厂模式,工厂方法模式,抽象工厂模式;

2. 简单工厂模式

又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

优点: 实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责
缺点: 工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂

2.1. 角色

  1. Factory类:负责创建具体产品的实例
  2. Product类:抽象产品类,定义产品子类的公共接口
  3. ConcreteProduct 类:具体产品类,实现Product父类的接口功能,也可添加自定义的功能

2.2. UML类图

工厂简单模式.png

php示例代码: Factory.class.php

  <?php 
  //简单工厂模式
  class Cat
  {
      function __construct()
      {
          echo "I am Cat class <br>";
      }
  }
  class Dog
  {
      function __construct()
      {
          echo "I am Dog class <br>";
      }
  }
  class Factory
  {
      public static function CreateAnimal($name){
          if ($name == 'cat') {
              return new Cat();
          } elseif ($name == 'dog') {
              return new Dog();
          }
      }
  }

  $cat = Factory::CreateAnimal('cat');
  $dog = Factory::CreateAnimal('dog');

3. 工厂方法模式

此模式中,通过定义一个抽象的核心工厂类,并定义创建产品对象的接口,创建具体产品实例的工作延迟到其工厂子类去完成。这样做的好处是核心类只关注工厂类的接口定义,而具体的产品实例交给具体的工厂子类去创建。当系统需要新增一个产品,无需修改现有系统代码,只需要添加一个具体产品类和其对应的工厂子类,使系统的扩展性变得很好,符合面向对象编程的开闭原则;

3.1. 角色

  1. Product:抽象产品类
  2. ConcreteProduct:具体产品类
  3. Factory:抽象工厂类
  4. ConcreteFactory:具体工厂类

3.2. UML类图

工厂方法模式.png

php示例代码 ConcreteFactory.class.php:

  <?php 
  interface Animal{
      public function run();
      public function say();
  }
  class Cat implements Animal
  {
      public function run(){
          echo "I ran slowly <br>";
      }
      public function say(){
          echo "I am Cat class <br>";
      }
  }
  class Dog implements Animal
  {
      public function run(){
          echo "I'm running fast <br>";
      }
      public function say(){
          echo "I am Dog class <br>";
      }
  }
  abstract class Factory{
      abstract static function createAnimal();
  }
  class CatFactory extends Factory
  {
      public static function createAnimal()
      {
          return new Cat();
      }
  }
  class DogFactory extends Factory
  {
      public static function createAnimal()
      {
          return new Dog();
      }
  }

  $cat = CatFactory::createAnimal();
  $cat->say();
  $cat->run();

  $dog = DogFactory::createAnimal();
  $dog->say();
  $dog->run();

4. 抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
此模式是对工厂方法模式的进一步扩展。在工厂方法模式中,一个具体的工厂负责生产一类具体的产品,即一对一的关系,但是,如果需要一个具体的工厂生产多种产品对象,那么就需要用到抽象工厂模式了。

4.1. 角色

  1. 抽象工厂(AbstractFactory):担任这个角色的是抽象工厂模式的核心,是与应用系统的商业逻辑无关的。
  2. 具体工厂(Factory):这个角色直接在客户端的调用下创建产品的实例,这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统商业逻辑紧密相关的。
  3. 抽象产品(AbstractProduct):担任这个角色的类是抽象工厂模式所创建的对象的父类,或它们共同拥有的接口
  4. 具体产品(Product):抽象工厂模式所创建的任何产品对象都是一个具体的产品类的实例。

4.2. 抽象工厂模式UML类图

抽象工厂模式.png

php示例代码: AbstructFactory.class.php

<?php 

interface TV{
  public function open();
  public function watch();
}

class HaierTv implements TV
{
  public function open()
  {
      echo "Open Haier TV <br>";
  }

  public function watch()
  {
      echo "I'm watching Haier TV <br>";
  }
}

class LenovoTv implements TV
{
  public function open()
  {
      echo "Open Lenovo TV <br>";
  }

  public function watch()
  {
      echo "I'm watching Lenovo TV <br>";
  }
}

interface PC{
  public function work();
  public function play();
}

class LenovoPc implements PC
{
  public function work()
  {
      echo "I'm working on a Lenovo computer <br>";
  }
  public function play()
  {
      echo "Lenovo computers can be used to play games <br>";
  }
}

class HaierPc implements PC
{
  public function work()
  {
      echo "I'm working on a Haier computer <br>";
  }
  public function play()
  {
      echo "Haier computers can be used to play games <br>";
  }
}

abstract class Factory{
  abstract public static function createPc();
  abstract public static function createTv();
}

class HaierFactory extends Factory
{
    public static function createTv()
    {
        return new HaierTv();
    }

    public static function createPc()
    {
        return new HaierPc();
    }

}

class LenovoFactory extends Factory
{
    public static function createTv()
    {
        return new LenovoTv();
    }

    public static function createPc()
    {
        return new LenovoPc();
    }

}

$haierFactory = new HaierFactory();
$haierTv = $haierFactory->createTv();
$haierTv->open();
$haierTv->watch();

$haierPc = $haierFactory->createPc();
$haierPc->work();
$haierPc->play();

$lenovoFactory = new LenovoFactory();
$lenovoPc = $lenovoFactory->createPc();
$lenovoPc->work();
$lenovoPc->play();

$lenovoTv = $lenovoFactory->createTv();
$lenovoTv->open();
$lenovoTv->watch();

php关键字

abstract(抽象) :

  1. 用abstract修饰的类表示这个类是一个抽象类,用abstract修饰的方法表示这个方法是一个抽象方法。
  2. 抽象方法是只有方法声明,而没有方法的实现内容。
  3. 抽象类不能被实例化,通常是将抽象方法做为子类方法重写使用的,且要把继承的抽象类里的方法都实现。

interface (接口):

  1. 如果一个抽象类里的所有方法都是抽象方法,且没有声明变量,所有成员都是public权限,那么这种特殊的抽象类就叫 接口
  2. interface即PHP接口,并用关键字implements来实现接口中方法,且必须完全实现

implements(实施,实现) :
implements是实现多个接口,接口的方法一般为空,必须重写才能使用

extends(继承) :
extends是继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法,如果类被声明为final,则不能被继承

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容

  • 工厂模式 工厂模式可以将对象的生产直接从new一个对象,改成调用一个工厂方法.这样的好处是:如果实例化的类名发生了...
    小山人阅读 681评论 0 3
  • 在开发大型系统时,往往会出现这样一种情况: 我有一部分基础数据,是类classA是从数据库A读取出来的,其他很多的...
    flamez57阅读 198评论 1 1
  • 前言 关于设计模式,是一个永远说不完的也说不清的话题。毕竟在编程的世界里,没有最好的设计模式,只有最合适的设计模式...
    VV木公子阅读 1,475评论 0 9
  • 写在最前: 1. 这并不是一本规范的讲解设计模式教程,但他是一本通俗易懂的讲解设计模式的指引。 2. 文章以PHP...
    山猫0131阅读 741评论 1 51
  • 1.从读者的角度设计文章 2.琢磨一个吸引人的好标题 3.讲自己身边人的故事 4.提炼重点并重复 5.节省读者的注...
    巴中张公子阅读 346评论 0 0