php设计模式如何实现(PHP设计模式(创建型))

wufei123 发布于 2024-01-07 阅读(244)

php零基础自学

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

php设计模式如何实现(PHP设计模式(创建型))

我们学习的设计模式分为三类:创建者模式、结构型模式、行为型模式;创建型模式与对象的创建有关;结构型模式处理类或对象的组合;而行为型模式是对类或对象怎样交互和怎样资源网分配职责进行描述;内容:本文介绍的是 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) { stat资源网ic::$instance = new static(); } return static::$instance; } /**

* 防止实例被克隆(这会创建实例的副本) */ private funct资源网ion __clone() { } /** * 防止反序列化(这将创建它的副本) */ private function __wakeup()

{ }}(二)多例模式(Multiton)● 定义在多例模资源网式中,多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例1. 通过实例容器保存容器2. 利用私有构造阻止外部构造。

3. 提供getInstantce()方法获取实例.资源网● 代码示例 两个对象通过一个类进行多次实例化abstract class Multiton { private static $instances = array();

public static f资源网unction getInstance() { $key = get_called_class() . serialize(func_get_args()); if (!isset(self::$in资源网stances[$key])) {

$rc = new ReflectionClass(get_called_class()); self::$instances[$key] = $rc->newIns资源网tanceArgs(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 Mul资源网titon { public function __construct($string = my, $string2 = darling) {

echo "Goodbye $string $string资源网2\n"; }}$a = Hello::getInstance(World); $b = Hello::getInstance(bob);

// $a !== $b $c = Hello::getIns资源网tance(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 S资源网how();}//具体产品A类class ProductA extends Product{ public function Show() {

echo "生产出了产品A"; }}//具体产品B类cla资源网ss ProductB extends Product{ public function Show() { echo "生产出了产品B"; }

}abstract class Factory{ publ资源网ic abstract function Manufacture();}//工厂A类 - 生产A类产品class FactoryA extends Factory{

public function Ma资源网nufacture() { return new ProductA(); }}//工厂B类 - 生产B类产品class FactoryB extends Factory{

public function资源网 Manufacture() { return new ProductB(); }}(四)抽象工厂模式(Abstract Factory)● 定义在不指定具体类的情况下创建一系列相关或依赖对象。

通常创资源网建的类都实现相同的接口 抽象工厂的客户并不关心这些对象是如何创建的,它只是知道它们是如何一起运行的● 代码示例 : 有两个工厂,A 工厂负责运输,B 工厂生产数码产品.interface Produc资源网t

{ public function calculatePrice(): int;}class ShippableProduct implements Product{ /** * @var floa资源网t */

private $productPrice; /** * @var float */ private $shippingCosts; public function __construct(i资源网nt $productPrice, int $shippingCosts)

{ $this->productPrice = $productPrice; $this->shippingCosts = $资源网shippingCosts; } public function calculatePrice(): int

{ return $this->productPrice + $this->shipping资源网Costs; }}class DigitalProduct implements Product{ /** * @var int

*/ private $price; public function _资源网_construct(int $price) { $this->price = $price; } public function calculatePrice(): int

{ return $thi资源网s->price; }}class ProductFactory{ const SHIPPING_COSTS = 50; public function createShippableProduct(资源网int $price): Product

{ return new ShippableProduct($price, self::SHIPPING_COSTS); } public function c资源网reateDigitalProduct(int $price): Product

{ return new DigitalProduct($price); }}(五)简单工厂模式(Simple Fact资源网ory)● 定义简单工厂模式是一个精简版的工厂模式工厂角色-具体产品-抽象产品● 代码示例 :

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

interface fruit{ /** * 生长 */ public func资源网tion grow(); /** * 种植 */ public function plant(); /** * 收获 */

public function harvest(); /** * 吃 */ p资源网ublic 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"; } //取苹果树的年龄

publ资源网ic function getTreeAge(){ return $this->treeAge; } //设置苹果树的年龄 public function setTreeAge($age){ $thi资源网s->treeAge = $age;

return true; }}class grape implements fruit{ //葡萄是否有籽 private $seedLess; public fu资源网nction grow(){ echo "apple grow";

} public function plant(){ echo "apple plant"; } public function ha资源网rvest(){ echo "apple harvest"; } public function eat(){

echo "apple eat"; } //有无籽取值 public function g资源网etSeedLess(){ 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 Ex资源网ception

{ public $msg; public $errType; public function __construct($msg = , $errType = 1){ $this->ms资源网g = $msg;

$this->errType = $errType; } }/** * 获取水果实例化的方法 */try{ $appleInstance = farmer::factory(appl资源网e); var_dump($appleInstance);

}catch(badFruitException $err){ echo $err->msg . "_______" . $err->errT资源网ype;}(六)原型模式(Prototype)● 定义相比正常创建一个对象 (new Foo () ),首先创建一个原型,然后克隆它会更节省开销。

● 代码示例 : 为每一本书设置标题abstract 资源网class BookPrototype{ /** * @var string */ protected $title = 0; /** * @var string

*/ protected $categ资源网ory; abstract public function __clone(); public function getTitle(): string { return $this->title;

} 资源网public function setTitle($title) { $this->title = $title; }}class BarBookPrototype extends BookProto资源网type

{ /** * @var string */ protected $category = Bar; public function __clone() { }}class FooBookPro资源网totype extends BookPrototype

{ /** * @var string */ protected $category = Foo; public function __clon资源网e() { }}$fooPrototype = new FooBookPrototype();

$barPrototype = new BarBookPrototype();for ($i = 5; $资源网i setTitle(Foo Book No . $i);

var_dump(new FooBookPrototype == $book);}for ($i = 0; $i setTitle(Bar B资源网ook No . $i);

var_dump(new BarBookPrototype == $book);}(七)对象池模式(Pool)● 定义对象池可以用于构造并且存放一系列的对象并在需要时获取调用资源网在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。

在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在短期时间内就可以获得所需的对象● 代码示例class F资源网actory { protected static $products = array();

public static function pushProduct(Product $product) {资源网 self::$products[$product->getId()] = $product;

} public static function getProduct($id) { return iss资源网et(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)->ge资源网tId());

// firstprint_r(Factory::getProduct(second)->getId());// second(八)建造者模式(Builder)● 定义将一个复杂对象的构资源网建与它的表示分离,使得同样的构建过程可以创建不同的表示

● 2)代码示例 建造相同标准的卡车和汽车类似于变形金刚,相同的零件进行不同的组合.● 分为 Director 导演者,负责构建、BuilderI资源网nterface 构建接口,规范建造标准、TruckBuilder 构建卡车类 CarBuilder 构建汽车类。

Vehicle 零部件公共类、Truck Car Engine Wheel Door 资源网零部件类、DirectorTest 测试类class Director{ public function build(BuilderInterface $builder): Vehicle

{ $bui资源网lder->createVehicle(); $builder->addDoors(); $builder->addEngine(); $builder->addWheel(); return $bu资源网ilder->getVehicle();

}}interface BuilderInterface{ public function createVehicle(); public function a资源网ddWheel(); public function addEngine();

public function addDoors(); public function getVehicle(): Veh资源网icle;}class TruckBuilder implements BuilderInterface

{ /** * @var Truck */ private $truck; public fun资源网ction addDoors() { $this->truck->setPart(rightDoor, new Door());

$this->truck->setPart(leftDoor, new 资源网Door()); } public function addEngine() { $this->truck->setPart(truckEngine, new Engine());

} public f资源网unction addWheel() { $this->truck->setPart(wheel1, new Wheel()); $this->truck->setPart(wheel2, new W资源网heel());

$this->truck->setPart(wheel3, new Wheel()); $this->truck->setPart(wheel4, new Wheel()); $thi资源网s->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 func资源网tion 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(en资源网gine, 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 Dire资源网ctor())->build($carBuilder);

}}$directorTest = new DirectorTest();var_dump($directorTest->testCanBuil资源网dTruck());var_dump($directorTest->testCanBuildCar());

以上就是PHP设计模式(创建型)的详细内容,更多请关注其它相关文章!更多技巧请《转发 + 关注资源网》哦!

亲爱的读者们,感谢您花时间阅读本文。如果您对本文有任何疑问或建议,请随时联系我。我非常乐意与您交流。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。