您好,登錄后才能下訂單哦!
PHP設(shè)計模式的創(chuàng)建型有哪幾種?相信很多新手小白對PHP設(shè)計模式的創(chuàng)建型的了解處于懵懂狀態(tài),通過這篇文章的總結(jié),希望你能有所收獲。
我們學(xué)習(xí)的設(shè)計模式分為三類:創(chuàng)建者模式、結(jié)構(gòu)型模式、行為型模式;創(chuàng)建型模式與對象的創(chuàng)建有關(guān);結(jié)構(gòu)型模式處理類或?qū)ο蟮慕M合;而行為型模式是對類或?qū)ο笤鯓咏换ズ驮鯓臃峙渎氊?zé)進行描述;
PHP 設(shè)計模式的創(chuàng)建型包括:單例模式(Singleton), 多例模式(Multiton), 工廠方法模式(Factory Method), 抽象工廠模式(Abstract Factory), 簡單工廠模式(Simple Factory), 原型模式(Prototype), 對象池模式(Pool), 建造者模式(Builder)
(一)單例模式(Singleton)
● 定義
保證一個類只有一個實例,并且提供一個訪問它的全局訪問點。系統(tǒng)內(nèi)存中該類只存在一個對象,節(jié)省了系統(tǒng)資源,對于一些需要頻繁創(chuàng)建銷毀的對象,使用單例模式可以提高系統(tǒng)性能。
● 代碼示例
class Singleton { /** * @var Singleton */ private static $instance; /** * 不允許從外部調(diào)用以防止創(chuàng)建多個實例 * 要使用單例,必須通過 Singleton::getInstance() 方法獲取實例 */ private function __construct() { } /** * 通過懶加載獲得實例(在第一次使用的時候創(chuàng)建) */ public static function getInstance(): Singleton { if (null === static::$instance) { static::$instance = new static(); } return static::$instance; } /** * 防止實例被克?。ㄟ@會創(chuàng)建實例的副本) */ private function __clone() { } /** * 防止反序列化(這將創(chuàng)建它的副本) */ private function __wakeup() { } }
(二)多例模式(Multiton)
● 定義
在多例模式中,多例類可以有多個實例,而且多例類必須自己創(chuàng)建、管理自己的實例,并向外界提供自己的實例。1. 通過實例容器保存容器。2. 利用私有構(gòu)造阻止外部構(gòu)造。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)
● 定義
將類的實例化(具體產(chǎn)品的創(chuàng)建)延遲到工廠類的子類(具體工廠)中完成,即由子類來決定應(yīng)該實例化(創(chuàng)建)哪一個類
● 代碼示例 : 小成有一間塑料加工廠(僅生產(chǎn) A 類產(chǎn)品);隨著客戶需求的變化,客戶需要生產(chǎn) B 類產(chǎn)品。改變原有塑料加工廠的配置和變化非常困難,假設(shè)下一次客戶需要再發(fā)生變化,再次改變將增大非常大的成本;小成決定置辦塑料分廠 B 來生產(chǎn) B 類產(chǎn)品。
abstract class Product{ public abstract function Show(); } //具體產(chǎn)品A類 class ProductA extends Product{ public function Show() { echo "生產(chǎn)出了產(chǎn)品A"; } } //具體產(chǎn)品B類 class ProductB extends Product{ public function Show() { echo "生產(chǎn)出了產(chǎn)品B"; } } abstract class Factory{ public abstract function Manufacture(); } //工廠A類 - 生產(chǎn)A類產(chǎn)品 class FactoryA extends Factory{ public function Manufacture() { return new ProductA(); } } //工廠B類 - 生產(chǎn)B類產(chǎn)品 class FactoryB extends Factory{ public function Manufacture() { return new ProductB(); } }
(四)抽象工廠模式(Abstract Factory)
● 定義
在不指定具體類的情況下創(chuàng)建一系列相關(guān)或依賴對象。 通常創(chuàng)建的類都實現(xiàn)相同的接口。 抽象工廠的客戶并不關(guān)心這些對象是如何創(chuàng)建的,它只是知道它們是如何一起運行的。
● 代碼示例 : 有兩個工廠,A 工廠負責(zé)運輸,B 工廠生產(chǎn)數(shù)碼產(chǎn)品.
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)
● 定義
簡單工廠模式是一個精簡版的工廠模式。工廠角色-具體產(chǎn)品-抽象產(chǎn)品
● 代碼示例 :
一個農(nóng)場,要向市場銷售水果。農(nóng)場里有三種水果 蘋果、葡萄,我們設(shè)想:1、水果有多種屬性,每個屬性都有不同,但是,他們有共同的地方 | 生長、種植、收貨、吃。將來有可能會增加新的水果、我們需要定義一個接口來規(guī)范他們必須實現(xiàn)的方法.
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; } //設(shè)置蘋果樹的年齡 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; } //設(shè)置有籽無籽 public function setSeedLess($seed){ $this->seedLess = $seed; return true; } } class farmer { //定義個靜態(tài)工廠方法 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)
● 定義
相比正常創(chuàng)建一個對象 (new Foo () ),首先創(chuàng)建一個原型,然后克隆它會更節(jié)省開銷。
● 代碼示例 : 為每一本書設(shè)置標題
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)
● 定義
對象池可以用于構(gòu)造并且存放一系列的對象并在需要時獲取調(diào)用。在初始化實例成本高,實例化率高,可用實例不足的情況下,對象池可以極大地提升性能。在創(chuàng)建對象(尤其是通過網(wǎng)絡(luò))時間花銷不確定的情況下,通過對象池在短期時間內(nèi)就可以獲得所需的對象。
● 代碼示例
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)
● 定義
將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示
● 2)代碼示例 建造相同標準的卡車和汽車。類似于變形金剛,相同的零件進行不同的組合.
● 分為 Director 導(dǎo)演者,負責(zé)構(gòu)建、BuilderInterface 構(gòu)建接口,規(guī)范建造標準、TruckBuilder 構(gòu)建卡車類 CarBuilder 構(gòu)建汽車類
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設(shè)計模式的創(chuàng)建型的詳細內(nèi)容了,看完之后是否有所收獲呢?如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。