php+设计模式代码,PHP设计模式(创建型)

前言

随着编程项目经验的增加,从服务于业务逻辑到针对项目的全局设计。认识到设计模式在开发过程中 \的重要性,遵循 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());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值