代码说

code is poetry

代码说    
碎碎念:要做就做第一!  换一换

php设计模式之工厂模式

作者:coderzheng 发布于:2014-7-12 22:09 Saturday 分类:php  阅读模式

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况, 新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。
问题
      你如何能轻松方便地建立这么" 复杂 " 的对象即操作中不需要粘贴复制呢?
解决方法
      建立一个工厂(一个函数或一个类方法)来制造新的对象。

我们来看一个实际的例子:书店上架N种图书,图书有价格、名称和作者三种属性,用户购买图书时会有不同的等级,比如:普通用户、VIP用户、内部员工,每一种等级对象不同的折扣。现在要求根据用户的不同等级和购书的数量计算用户应付金额。
我们来看用工厂模式编写的代码:

user.php:
<?php
interface User {
     public function getName();
     public function setName($_name);
     public function getDiscount();
}

abstract class AbstractUser implements User {
     private $name = "";
     protected $discount = 0;
     protected $grade = "";

     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";
}

userFactory.php:
<?php
require_once("user.php");

abstract class UserFactory {
     static function createUser($_grade, $_name) {
          if ("NormalUser" == $_grade) {
               return new NormalUser($_name);
          } elseif ("VipUser" == $_grade) {
               return new VipUser($_name);
          } elseif ("InnerUser" == $_grade) {
               return new InnerUser($_name);
          } else {
               echo "some exception";
               return null;
          }
     }
}

product.php:
<?php
interface Product {
     public function getProductName();
     public function getProductPrice();
}

interface Book extends Product {
     public function getAuthor();
}

class BookOnline implements Book {
     private $productName;
     private $productPrice;
     private $author;

     public function __construct($_bookName) {
          $this->productName = $_bookName;
     }

     public function getProductName() {
          return $this->productName;
     }

     public function getProductPrice() {
          $this->productPrice = 100;
          return $this->productPrice;
     }

     public function getAuthor() {
          return $this->author;
     }
}


productFactory.php:

<?php
require_once("product.php");

abstract class ProductFactory {
     public static function createProduct($_type, $_name) {
          if ("book" == $_type) {
               return new BookOnline($_name);
          } else {
               return null;
          }
     }
}

productSettle.php:
<?php
include_once("user.php");
include_once("product.php");

class ProductSettle {
     public static function finalPrice(User $_user,Product $_product,$number =1) {
          $price = $_user->getDiscount() * $_product->getProductPrice() * $number;
          return $price;
     }

     public static function getInfo(User $user,$product,$number) {
          if ($user != null & $product != null ) {
               $price = ProductSettle::finalPrice($user,$product,$number);
               $str = "您好,尊敬的用户" . $user->getName() . "<br />";
               $str .= "您的级别是 " . $user->getGrade() . "<br />";
               $str .= "您的折扣是" . $user->getDiscount() . "<br />";
               $str .= "够买 $number 本 《" .$product->getProductName();
               $str .= ">>的价格是 $price <br /><br />";
               return $str;
          } elseif (null==$user) {
               return "用户不存在";
          } else {
               return "产品不存在";
          }
     }
}

test_45.php:
<?php
header("Content-type:text/html;charset=utf-8");
include_once("userFactory.php");
include_once("productFactory.php");
include_once("productSettle.php");

$number = 10;
$bookName = "设计模式";
$book = ProductFactory::createProduct("book", $bookName);

$normalUser = UserFactory::createUser("NormalUser", "Tom");
$vipUser = UserFactory::createUser("VipUser", "Jack");
$innerUser = UserFactory::createUser("InnerUser", "Jerry");

echo ProductSettle::getInfo($normalUser, $book, $number);
echo ProductSettle::getInfo($vipUser, $book, $number);
echo ProductSettle::getInfo($innerUser, $book, $number);


在test_45.php中,我们看到由于类的职责非常明了,相应的方法也已经封装好,因此php语句写起来非常简单并且清晰易懂。

标签: php php设计模式

你可以发表评论、引用到你的网站或博客,或通过RSS 2.0订阅这个博客的所有文章。
上一篇: 人鬼过河问题  |  下一篇:php设计模式之单例模式