php设计模式 — 简单工厂模式(静态工厂方法模式)

#cnblogs_post_body > div:nth-child(8) > pre

概念

简单工厂模式 【静态工厂方法模式】(Static Factory Method)
是类的创建模式

工厂模式的几种形态:
  1、简单工厂模式(Simple Factory) |又叫做  静态工厂方法模式(Static Factory Method)
  2、工厂方法模式(Factory Method) |又叫做 多态性工厂模式(Polymorphic Factory)
  3、抽象工厂模式(Abstract Factory) |又叫做 工具箱模式(ToolKit)

配图

Delevin、博客

代码实例1

直接将代码运行即可,都是测试过的

<?php

/**
 * 一个事例
 *
 * 一个农场,要向市场销售水果
 * 农场里有三种水果 苹果、葡萄
 * 我们设想:1、水果有多种属性,每个属性都有不同,但是,他们有共同的地方 |  生长、种植、收货、吃
 *              2、将来有可能会增加新的水果、我们需要定义一个接口来规范他们必须实现的方法
 *              3、我们需要获取某个水果的类,要从农场主那里去获取某个水果的实例,来知道如何生长、种植、收货、吃
 */


/**
 * 虚拟产品接口类
 * 定义好需要实现的方法
 */

interface fruit{

    /**
     * 生长
     */
    public function grow();

    /**
     * 种植
     */
    public function plant();

    /**
     * 收获
     */
    public function harvest();

    /**
     * 吃
     */
    public function eat();
    
}


/**
 * 定义具体产品类 苹果
 * 首先,我们要实现所继承的接口所定义的方法
 * 然后定义苹果所特有的属性,以及方法
 */
class apple implements fruit{

    //苹果树有年龄
    private $treeAge;

    //苹果有颜色
    private $color;

    public function grow(){
        echo "grape grow";
    }

    public function plant(){
        echo "grape plant";
    }

    public function harvest(){
        echo "grape harvest";
    }

    public function eat(){
        echo "grape eat";
    }

    //取苹果树的年龄
    public function getTreeAge(){
        return $this->treeAge;
    }

    //设置苹果树的年龄
    public function setTreeAge($age){
        $this->treeAge = $age;
        return trie;
    }

}

/**
 * 定义具体产品类 葡萄
 * 首先,我们要实现所继承的接口所定义的方法
 * 然后定义葡萄所特有的属性,以及方法
 */
class grape implements fruit{


    //葡萄是否有籽
    private $seedLess;

    public function grow(){
        echo "apple grow";
    }

    public function plant(){
        echo "apple plant";
    }

    public function harvest(){
        echo "apple harvest";
    }

    public function eat(){
        echo "apple eat";
    }

    //有无籽取值
    public function getSeedLess(){
        return $this->seedLess;
    }

    //设置有籽无籽
    public function setSeedLess($seed){
        $this->seedLess = $seed;
        return true;
    }

}


/**
 *农场主类 用来获取实例化的水果
 *
 */
class farmer{

    //定义个静态工厂方法
    public static function factory($fruitName){
        switch ($fruitName) {
            case 'apple':
                return new apple();
                break;
            case 'grape':
                return new grape();
                break;
            default:
                throw new badFruitException("Error no the fruit", 1);
                break;
        }
    }
}

class badFruitException extends Exception{
    public $msg;
    public $errType;
    public function __construct($msg = '' , $errType = 1){
        $this->msg = $msg;
        $this->errType = $errType;
    }    
}


/**
 * 获取水果实例化的方法
 */
try{
    $appleInstance = farmer::factory('apple');
    var_dump($appleInstance);
}catch(badFruitException $err){
    echo $err->msg . "_______" . $err->errType;
}



代码实例2

1、首先大家要明白,简单工厂模式有三个角色

  1、抽象角色

  2、具体角色

  3、工厂角色 : 负责获取某个具体角色的实例

2、下面的事例,是使用抽象类直接创建具体产品实例。省去了工厂角色

  这里有几个需要注意的点:

  1、抽象类AbstractUser 有一个方法getInstance 这个方法是静态的,不然我们必须要实例化才能使用,但是它是一个抽象类,不能实例化。所以必须要是静态的方法

  2、大家还发现getInstance 定义了final ,final的意义就是这个方法不需要被具体类继承

<?
/*
* 定义了 User接口.
* 和子类 NormalUser,VipUser,InnerUser 
*/
//User接口,定义了三个抽象方法.
interface User{
    public function getName();
    public function setName($_name);
    public function getDiscount();
}

abstract class AbstractUser implements User{
    private $name = ""; //名字
    protected  $discount = 0; //折扣
    protected  $grade = "";  //级别
    
    final public static function getInstance($userType , $name){
        if(class_exists($userType)){
            $instance = new $userType($name);
            if($instance instanceof self){
                return $instance;
            }
        }
        throw new Exception("Error no the userType");
    }

    public function __construct($_name){
        $this->setName($_name);
    }
    public function getName(){
        return $this->name;
    }
    public function setName($_name){
        $this->name = $_name;
    }
    public function getDiscount(){
        return $this->discount;
    }
    
    public function getGrade(){
        return $this->grade;
    }
}

class NormalUser extends AbstractUser  {
    protected  $discount = 1.0;
    protected  $grade = "NormalUser";
}

class VipUser extends AbstractUser {
    protected  $discount = 0.8;
    protected  $grade = "VipUser";
}

class InnerUser extends AbstractUser {
    protected  $discount = 0.7;
    protected  $grade = "InnerUser";
}


$user = AbstractUser::getInstance('NormalUser' , 'zhangsan');
var_dump($user);