前言
隨著程式設計專案經驗的增加,從服務業務邏輯到針對專案的全域設計。認識到設計模式在開發過程中 \的重要性,遵循 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設計模式(創建型)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。

Fibers在PHP8.1中引入,提升了並發處理能力。 1)Fibers是一種輕量級的並發模型,類似於協程。 2)它們允許開發者手動控制任務的執行流,適合處理I/O密集型任務。 3)使用Fibers可以編寫更高效、響應性更強的代碼。

PHP社區提供了豐富的資源和支持,幫助開發者成長。 1)資源包括官方文檔、教程、博客和開源項目如Laravel和Symfony。 2)支持可以通過StackOverflow、Reddit和Slack頻道獲得。 3)開發動態可以通過關注RFC了解。 4)融入社區可以通過積極參與、貢獻代碼和學習分享來實現。

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3 Linux新版
SublimeText3 Linux最新版