PHP设计模式(创建型)

互联网 19-9-4
前言

随着编程项目经验的增加,从服务于业务逻辑到针对项目的全局设计。认识到设计模式在开发过程中 \的重要性,遵循 S.O.L.I.D 五大基准原则。它拓展了我的视野,让代码更加灵活,看起来更加富有美感.\美是构建万物的哲学思想.

我们学习的设计模式分为三类:创建者模式、结构型模式、行为型模式;创建型模式与对象的创建有关;结构型模式处理类或对象的组合;而行为型模式是对类或对象怎样交互和怎样分配职责进行描述;

内容:本文介绍的是 PHP 设计模式的创建型一篇。包括:单例模式(Singleton), 多例模式(Multiton), 工厂方法模式(Factory Method), 抽象工厂模式(Abstract Factory), 简单工厂模式(Simple Factory), 原型模式(Prototype), 对象池模式(Pool), 建造者模式(Builder)

推荐:《PHP教程》

(一)单例模式(Singleton)

● 定义

保证一个类只有一个实例,并且提供一个访问它的全局访问点。系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。

● 代码示例

class Singleton {     /**     * @var Singleton     */     private static $instance;     /**     * 不允许从外部调用以防止创建多个实例     * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例     */     private function __construct()     {     }     /**     * 通过懒加载获得实例(在第一次使用的时候创建)     */     public static function getInstance(): Singleton     {         if (null === static::$instance) {             static::$instance = new static();         }         return static::$instance;     }     /**     * 防止实例被克隆(这会创建实例的副本)     */     private function __clone()     {     }     /**     * 防止反序列化(这将创建它的副本)     */     private function __wakeup()     {     } }

(二)多例模式(Multiton)

● 定义

在多例模式中,多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。1. 通过实例容器保存容器。2. 利用私有构造阻止外部构造。3. 提供getInstantce()方法获取实例.

● 代码示例 两个对象通过一个类进行多次实例化

abstract class Multiton {      private static $instances = array();      public static function getInstance() {          $key = get_called_class() . serialize(func_get_args());         if (!isset(self::$instances[$key])) {              $rc = new ReflectionClass(get_called_class());             self::$instances[$key] = $rc->newInstanceArgs(func_get_args());         }         return self::$instances[$key];      }     /**      * 该私有对象阻止实例被克隆      */     private function __clone()     {     }     /**      * 该私有方法阻止实例被序列化      */     private function __wakeup()     {     } }  class Hello extends Multiton {      public function __construct($string = 'World') {          echo "Hello $string\n";      }  }  class GoodBye extends Multiton {      public function __construct($string = 'my', $string2 = 'darling') {          echo "Goodbye $string $string2\n";      } } $a = Hello::getInstance('World');  $b = Hello::getInstance('bob');  // $a !== $b  $c = Hello::getInstance('World');  // $a === $c  $d = GoodBye::getInstance();  $e = GoodBye::getInstance(); // $d === $e  $f = GoodBye::getInstance('your');  // $d !== $f

(三)工厂方法模式(Factory Method)

● 定义

将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类

● 代码示例 : 小成有一间塑料加工厂(仅生产 A 类产品);随着客户需求的变化,客户需要生产 B 类产品。改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;小成决定置办塑料分厂 B 来生产 B 类产品。

abstract class Product{     public abstract function Show(); } //具体产品A类 class  ProductA extends  Product{     public function Show() {         echo "生产出了产品A";     } } //具体产品B类 class  ProductB extends  Product{     public function Show() {         echo "生产出了产品B";     } } abstract class Factory{     public abstract function Manufacture(); } //工厂A类 - 生产A类产品 class  FactoryA extends Factory{     public function Manufacture() {         return new ProductA();     } } //工厂B类 - 生产B类产品 class  FactoryB extends Factory{     public function Manufacture() {         return new ProductB();     } }

(四)抽象工厂模式(Abstract Factory)

● 定义

在不指定具体类的情况下创建一系列相关或依赖对象。 通常创建的类都实现相同的接口。 抽象工厂的客户并不关心这些对象是如何创建的,它只是知道它们是如何一起运行的。

● 代码示例 : 有两个工厂,A 工厂负责运输,B 工厂生产数码产品.

interface Product {     public function calculatePrice(): int; } class ShippableProduct implements Product {     /**      * @var float      */     private $productPrice;     /**      * @var float      */     private $shippingCosts;     public function __construct(int $productPrice, int $shippingCosts)     {         $this->productPrice = $productPrice;         $this->shippingCosts = $shippingCosts;     }     public function calculatePrice(): int     {         return $this->productPrice + $this->shippingCosts;     } } class DigitalProduct implements Product {     /**      * @var int      */     private $price;     public function __construct(int $price)     {         $this->price = $price;     }     public function calculatePrice(): int     {         return $this->price;     } } class ProductFactory {     const SHIPPING_COSTS = 50;     public function createShippableProduct(int $price): Product     {         return new ShippableProduct($price, self::SHIPPING_COSTS);     }     public function createDigitalProduct(int $price): Product     {         return new DigitalProduct($price);     } }

(五)简单工厂模式(Simple Factory)

● 定义

简单工厂模式是一个精简版的工厂模式。工厂角色-具体产品-抽象产品

● 代码示例 :

一个农场,要向市场销售水果。农场里有三种水果 苹果、葡萄,我们设想:1、水果有多种属性,每个属性都有不同,但是,他们有共同的地方 | 生长、种植、收货、吃。将来有可能会增加新的水果、我们需要定义一个接口来规范他们必须实现的方法.

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

(六)原型模式(Prototype)

● 定义

相比正常创建一个对象 (new Foo () ),首先创建一个原型,然后克隆它会更节省开销。

● 代码示例 : 为每一本书设置标题

abstract class BookPrototype {     /**     * @var string     */     protected $title = 0;     /**     * @var string     */     protected $category;     abstract public function __clone();     public function getTitle(): string     {         return $this->title;     }     public function setTitle($title)     {        $this->title = $title;     } } class BarBookPrototype extends BookPrototype {     /**     * @var string     */     protected $category = 'Bar';     public function __clone()     {     } } class FooBookPrototype extends BookPrototype {     /**     * @var string     */     protected $category = 'Foo';     public function __clone()     {     } } $fooPrototype = new FooBookPrototype(); $barPrototype = new BarBookPrototype(); for ($i = 5; $i < 10; $i++) {     $book = clone $fooPrototype;     $book->setTitle('Foo Book No ' . $i);     var_dump(new FooBookPrototype == $book); } for ($i = 0; $i < 5; $i++) {     $book = clone $barPrototype;     $book->setTitle('Bar Book No ' . $i);     var_dump(new BarBookPrototype == $book); }

(七)对象池模式(Pool)

● 定义

对象池可以用于构造并且存放一系列的对象并在需要时获取调用。在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在短期时间内就可以获得所需的对象。

● 代码示例

class Factory {     protected static $products = array();     public static function pushProduct(Product $product) {         self::$products[$product->getId()] = $product;     }     public static function getProduct($id) {         return isset(self::$products[$id]) ? self::$products[$id] : null;     }     public static function removeProduct($id) {         if (array_key_exists($id, self::$products)) {             unset(self::$products[$id]);         }     } } Factory::pushProduct(new Product('first')); Factory::pushProduct(new Product('second')); print_r(Factory::getProduct('first')->getId()); // first print_r(Factory::getProduct('second')->getId()); // second

(八)建造者模式(Builder)

● 定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

● 2)代码示例 建造相同标准的卡车和汽车。类似于变形金刚,相同的零件进行不同的组合.

● 分为 Director 导演者,负责构建、BuilderInterface 构建接口,规范建造标准、TruckBuilder 构建卡车类 CarBuilder 构建汽车类

Vehicle 零部件公共类、Truck Car Engine Wheel Door 零部件类、DirectorTest 测试类

class Director {     public function build(BuilderInterface $builder): Vehicle     {         $builder->createVehicle();         $builder->addDoors();         $builder->addEngine();         $builder->addWheel();         return $builder->getVehicle();     } } interface BuilderInterface {     public function createVehicle();     public function addWheel();     public function addEngine();     public function addDoors();     public function getVehicle(): Vehicle; } class TruckBuilder implements BuilderInterface {     /**     * @var Truck     */     private $truck;     public function addDoors()     {         $this->truck->setPart('rightDoor', new Door());         $this->truck->setPart('leftDoor', new Door());     }     public function addEngine()     {         $this->truck->setPart('truckEngine', new Engine());     }     public function addWheel()     {         $this->truck->setPart('wheel1', new Wheel());         $this->truck->setPart('wheel2', new Wheel());         $this->truck->setPart('wheel3', new Wheel());         $this->truck->setPart('wheel4', new Wheel());         $this->truck->setPart('wheel5', new Wheel());         $this->truck->setPart('wheel6', new Wheel());     }     public function createVehicle()     {         $this->truck = new Truck();     }     public function getVehicle(): Vehicle     {         return $this->truck;     } } class CarBuilder implements BuilderInterface {     /**     * @var Car     */     private $car;     public function addDoors()     {         $this->car->setPart('rightDoor', new Door());         $this->car->setPart('leftDoor', new Door());         $this->car->setPart('trunkLid', new Door());     }     public function addEngine()     {         $this->car->setPart('engine', new Engine());     }     public function addWheel()     {         $this->car->setPart('wheelLF', new Wheel());         $this->car->setPart('wheelRF', new Wheel());         $this->car->setPart('wheelLR', new Wheel());         $this->car->setPart('wheelRR', new Wheel());     }     public function createVehicle()     {         $this->car = new Car();     }     public function getVehicle(): Vehicle     {         return $this->car;     } } abstract class Vehicle {     /**     * @var object[]     */     private $data = [];     /**     * @param string $key     * @param object $value     */     public function setPart($key, $value)     {         $this->data[$key] = $value;     } } class Truck extends Vehicle { } class Car extends Vehicle { } class Engine extends Vehicle { } class Wheel extends Vehicle { } class Door extends Vehicle { } class DirectorTest {     public function testCanBuildTruck()     {         $truckBuilder = new TruckBuilder();         return (new Director())->build($truckBuilder);     }     public function testCanBuildCar()     {         $carBuilder = new CarBuilder();         return (new Director())->build($carBuilder);     } } $directorTest = new DirectorTest(); var_dump($directorTest->testCanBuildTruck()); var_dump($directorTest->testCanBuildCar());

以上就是PHP设计模式(创建型)的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: php设计模式
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:超详细分析php docker的原理及作用

相关资讯