怎樣做企業(yè)手機(jī)網(wǎng)站工具站seo
單例模式
-
含義描述
應(yīng)用程序中最多只有該類的一個(gè)實(shí)例存在
-
應(yīng)用場景
常應(yīng)用于數(shù)據(jù)庫類設(shè)計(jì),采用單例模式,只連接一次數(shù)據(jù)庫,防止打開多個(gè)數(shù)據(jù)庫連接。
-
代碼示例
class Singleton {private static $instance; // 定義一個(gè)私有的靜態(tài)變量保存類的實(shí)例private function __construct() {} // 將構(gòu)造函數(shù)設(shè)為私有,防止外部直接創(chuàng)建對(duì)象public static function getInstance() {if (!self::$instance) { // 如果沒有實(shí)例化則進(jìn)行實(shí)例化操作self::$instance = new self();}return self::$instance; // 返回已經(jīng)實(shí)例化好的對(duì)象} }// 調(diào)用單例模式獲取實(shí)例 $obj1 = Singleton::getInstance(); $obj2 = Singleton::getInstance();var_dump($obj1 === $obj2); // true,兩次獲取到的都是同一個(gè)實(shí)例
工廠模式
-
含義描述
工廠設(shè)計(jì)模式常用于根據(jù)輸入?yún)?shù)的不同或者應(yīng)用程序配置的不同來創(chuàng)建一種專門用來實(shí)例化并返回其對(duì)應(yīng)的類的實(shí)例
-
應(yīng)用場景
1.后臺(tái)數(shù)據(jù)導(dǎo)出:比如可導(dǎo)出文件類型有excel、csv、xml等,同樣都是實(shí)現(xiàn)導(dǎo)出功能,但是要實(shí)例化的類是不同的,實(shí)現(xiàn)邏輯也不相同;
2.支付系統(tǒng):根據(jù)用戶選擇的支付方式實(shí)例化不同的支付類,比如積分、微信、支付寶等支付
3.緩存功能:一般有文件緩存、session、cookie等,他們的實(shí)例也是不同的。
-
代碼示例
<?php// 定義接口,定義所有對(duì)象的通用方法 interface ShapeInterface {public function draw(); }// 實(shí)現(xiàn)接口的具體類,畫一個(gè)圓形 class Circle implements ShapeInterface {public function draw(){echo "Drawing a circle.\n";} }// 實(shí)現(xiàn)接口的具體類,畫一個(gè)長方形 class Rectangle implements ShapeInterface {public function draw(){echo "Drawing a rectangle.\n";} }// 工廠類 class ShapeFactory {// 根據(jù)傳入的形狀類型生成對(duì)應(yīng)的對(duì)象public static function createShape($shapeType){if ($shapeType == 'circle') {return new Circle();} elseif ($shapeType == 'rectangle') {return new Rectangle();} else {throw new Exception("Invalid shape type: " . $shapeType);}} }// 使用工廠類生成對(duì)象并調(diào)用方法 try {$circle = ShapeFactory::createShape('circle');$circle->draw();$rectangle = ShapeFactory::createShape('rectangle');$rectangle->draw();// 嘗試創(chuàng)建無效的形狀類型$invalidShape = ShapeFactory::createShape('triangle'); } catch (Exception $e) {echo "Error: " . $e->getMessage(); }輸出結(jié)果: Drawing a circle. Drawing a rectangle. Error: Invalid shape type: triangle
在這個(gè)示例中,我們定義了一個(gè)ShapeInterface接口,它包含了一個(gè)draw()方法,用于繪制形狀。然后,我們創(chuàng)建了兩個(gè)實(shí)現(xiàn)該接口的具體類Circle和Rectangle,它們分別實(shí)現(xiàn)了draw()方法來繪制圓形和矩形。
接下來,我們創(chuàng)建了一個(gè)ShapeFactory工廠類,它包含一個(gè)靜態(tài)方法createShape(),該方法根據(jù)傳入的形狀類型(字符串)生成相應(yīng)的對(duì)象實(shí)例。在createShape()方法中,我們根據(jù)傳入的形狀類型使用條件語句創(chuàng)建對(duì)應(yīng)的對(duì)象,并返回該對(duì)象。如果傳入的形狀類型無效,我們將拋出一個(gè)異常。
最后,我們使用ShapeFactory類來生成圓形和矩形的對(duì)象,并調(diào)用它們的draw()方法來繪制形狀。同時(shí),我們也嘗試創(chuàng)建一個(gè)無效的形狀類型(三角形),以演示異常處理機(jī)制。
策略模式
-
含義描述
策略設(shè)計(jì)模式是一種行為設(shè)計(jì)模式,它允許你在運(yùn)行時(shí)改變對(duì)象的行為。在策略模式中,一個(gè)類的行為或其算法可以在運(yùn)行時(shí)更改應(yīng)用場景
-
應(yīng)用場景
- 商城促銷方式:對(duì)秒殺、滿減、打折等不同促銷方式用不同的算法計(jì)算不同的結(jié)算價(jià)格
- 日志系統(tǒng):根據(jù)日志的類型做不同的響應(yīng)
-
代碼示例
//我們將以一個(gè)簡單的日志記錄系統(tǒng)為例,其中我們可以選擇不同的日志策略來記錄信息。//首先,我們定義一個(gè)日志策略接口:<?php interface LoggingStrategy {public function log(string $message); }//然后,我們實(shí)現(xiàn)幾種不同的日志策略,例如控制臺(tái)日志、文件日志和數(shù)據(jù)庫日志:<?php class ConsoleLog implements LoggingStrategy {public function log(string $message) {echo "Console: " . $message . PHP_EOL;} }class FileLog implements LoggingStrategy {private $file;public function __construct(string $file) {$this->file = $file;}public function log(string $message) {file_put_contents($this->file, "File: " . $message . PHP_EOL, FILE_APPEND);} }class DatabaseLog implements LoggingStrategy {private $pdo;public function __construct(PDO $pdo) {$this->pdo = $pdo;}public function log(string $message) {$stmt = $this->pdo->prepare("INSERT INTO logs (message) VALUES (?)");$stmt->execute([$message]);} }//接下來,我們創(chuàng)建一個(gè)Logger類,該類使用策略模式來記錄日志:<?php class Logger {private $strategy;public function __construct(LoggingStrategy $strategy) {$this->strategy = $strategy;}public function setStrategy(LoggingStrategy $strategy) {$this->strategy = $strategy;}public function log(string $message) {$this->strategy->log($message);} }//最后,我們?cè)谥鞒绦蛑惺褂肔ogger類:<?php // 創(chuàng)建一個(gè)PDO實(shí)例用于數(shù)據(jù)庫連接(這里僅作示例,實(shí)際使用時(shí)需要配置數(shù)據(jù)庫連接參數(shù)) $pdo = new PDO('mysql:host=localhost;dbname=mydb', 'username', 'password');// 創(chuàng)建不同的日志策略實(shí)例 $consoleLog = new ConsoleLog(); $fileLog = new FileLog('path/to/logfile.log'); $databaseLog = new DatabaseLog($pdo);// 創(chuàng)建一個(gè)Logger實(shí)例,并設(shè)置初始的日志策略為控制臺(tái)日志 $logger = new Logger($consoleLog); $logger->log("This is a console log message.");// 更改日志策略為文件日志 $logger->setStrategy($fileLog); $logger->log("This is a file log message.");// 更改日志策略為數(shù)據(jù)庫日志 $logger->setStrategy($databaseLog); $logger->log("This is a database log message.");在這個(gè)例子中,Logger類是一個(gè)上下文類,它使用LoggingStrategy接口來定義日志記錄的行為。通過setStrategy方法,我們可以動(dòng)態(tài)地更改日志記錄的策略,從而在不同的場景下使用不同的日志記錄方式。這樣,如果我們想要添加新的日志策略,只需要實(shí)現(xiàn)LoggingStrategy接口,并在Logger中使用它即可,而不需要修改Logger類的代碼。
- 與工廠模式的區(qū)別
- 目的不同:工廠模式的目的是創(chuàng)建對(duì)象,根據(jù)傳入的參數(shù)或條件返回不同類型的對(duì)象;而策略模式的目的是在運(yùn)行時(shí)選擇不同的行為或算法。
- 關(guān)注點(diǎn)不同:工廠模式關(guān)注對(duì)象的創(chuàng)建過程,封裝了對(duì)象的創(chuàng)建邏輯;而策略模式關(guān)注行為或算法的選擇和切換。
- 使用場景不同:工廠模式通常用于處理對(duì)象的創(chuàng)建問題,如多數(shù)據(jù)庫選擇、類庫文件加載等;而策略模式通常用于處理算法或行為的選擇問題,如排序算法的選擇、支付方式的選擇等。
- 與工廠模式的區(qū)別
觀察者模式
-
含義描述
觀察者模式是一種軟件設(shè)計(jì)模式,屬于對(duì)象行為模式。它定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。
-
應(yīng)用場景
- 事件處理:觀察者模式常被用于事件處理機(jī)制,如圖形用戶界面(GUI)框架中的按鈕點(diǎn)擊事件、窗口的打開和關(guān)閉事件等。觀察者對(duì)象可以訂閱這些特定事件,并在事件發(fā)生時(shí)接收通知并執(zhí)行相應(yīng)的操作。
- 消息通知:在消息通知系統(tǒng)中,如聊天應(yīng)用、社交媒體平臺(tái)等需要實(shí)時(shí)消息傳遞的場景中,觀察者模式也得到了廣泛應(yīng)用。當(dāng)發(fā)布者發(fā)布新消息時(shí),訂閱該消息的觀察者會(huì)收到通知并進(jìn)行相應(yīng)的處理。
- 股票市場:在股票市場中,觀察者模式可以用于實(shí)現(xiàn)訂閱者監(jiān)聽發(fā)布者的狀態(tài)變化并作出響應(yīng)。
- 日志記錄:觀察者模式還可以用于實(shí)時(shí)日志記錄系統(tǒng)。在這種情況下,日志記錄器充當(dāng)被觀察者,而觀察者可以是日志分析器、報(bào)警系統(tǒng)等。當(dāng)日志發(fā)生變化時(shí),觀察者會(huì)收到通知并執(zhí)行相應(yīng)的操作,如生成報(bào)告、發(fā)送警報(bào)等。
- Redis中的發(fā)布訂閱:Redis中的基于頻道的發(fā)布訂閱也是觀察者模式的一個(gè)應(yīng)用實(shí)例。
-
代碼示例
在 PHP 中實(shí)現(xiàn)觀察者模式,可以定義一個(gè) Subject 類和一個(gè) Observer 接口。Subject 類維護(hù)一個(gè)觀察者列表,并提供添加、刪除和通知觀察者的方法。Observer 接口定義了觀察者需要實(shí)現(xiàn)的方法。下面是一個(gè)簡單的示例代碼,展示了如何在 PHP 中實(shí)現(xiàn)觀察者模式:<?php // Observer 接口 interface Observer {public function update(Subject $subject); }// ConcreteObserver 類 class ConcreteObserver implements Observer {private $name;public function __construct($name) {$this->name = $name;}public function update(Subject $subject) {echo "Observer {$this->name} received update: {$subject->getState()}\n";} }// Subject 類 class Subject {private $observers = [];private $state;public function attach(Observer $observer) {$this->observers[] = $observer;}public function detach(Observer $observer) {$key = array_search($observer, $this->observers);if ($key !== false) {unset($this->observers[$key]);}}public function notify() {foreach ($this->observers as $observer) {$observer->update($this);}}public function setState($state) {$this->state = $state;$this->notify();}public function getState() {return $this->state;} }// 使用示例 $subject = new Subject();$observer1 = new ConcreteObserver('Observer 1'); $observer2 = new ConcreteObserver('Observer 2');$subject->attach($observer1); $subject->attach($observer2);$subject->setState('New state');$subject->detach($observer1);$subject->setState('Another state');在上面的示例中,我們定義了一個(gè) Observer 接口,它包含了一個(gè) update 方法,用于接收主題的狀態(tài)更新。ConcreteObserver 類實(shí)現(xiàn)了 Observer 接口,并在 update 方法中打印接收到的更新信息。Subject 類維護(hù)了一個(gè)觀察者列表($observers),并提供了 attach 方法用于添加觀察者,detach 方法用于移除觀察者,以及 notify 方法用于通知所有觀察者。setState 方法用于設(shè)置主題的狀態(tài),并在狀態(tài)改變時(shí)調(diào)用 notify 方法通知觀察者。getState 方法用于獲取當(dāng)前的主題狀態(tài)。在使用示例中,我們創(chuàng)建了一個(gè)主題對(duì)象 $subject,并將兩個(gè)觀察者對(duì)象 $observer1 和 $observer2 添加到主題中。然后,我們通過調(diào)用 setState 方法改變主題的狀態(tài),并觀察者的 update 方法將被調(diào)用,打印接收到的更新信息。最后,我們通過調(diào)用 detach 方法移除了一個(gè)觀察者,并再次改變主題的狀態(tài),觀察者的更新信息將不再打印。
裝飾器模式
-
含義描述
裝飾器設(shè)計(jì)模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)或功能
-
應(yīng)用場景
- 游戲開發(fā):裝備各種不同的武器裝備增加各種屬性,如攻擊力、HP和防御等
- 點(diǎn)餐系統(tǒng):根據(jù)用戶選擇的不同商品規(guī)格和配料,計(jì)算價(jià)格和滿減優(yōu)惠
-
代碼示例
// 定義一個(gè)接口,表示被裝飾的對(duì)象 interface Coffee {public function getCost();public function getIngredients(); }// 創(chuàng)建一個(gè)實(shí)現(xiàn)了Coffee接口的具體對(duì)象,即被裝飾的對(duì)象 class SimpleCoffee implements Coffee {public function getCost() {return 1.99;}public function getIngredients() {return "Coffee";} }// 創(chuàng)建一個(gè)加奶咖啡裝飾器類,它包裝了Coffee對(duì)象 class CoffeeWithMilk extends SimpleCoffee implements Coffee {private $coffee;public function __construct(Coffee $coffee) {$this->coffee = $coffee;}public function getCost() {return $this->coffee->getCost() + 0.30;}public function getIngredients() {return $this->coffee->getIngredients() . ", Milk";} }// 創(chuàng)建一個(gè)加糖咖啡的裝飾器類,它也為Coffee對(duì)象添加額外的行為 class CoffeeWithSugar extends CoffeeWithMilk {public function getCost() {return parent::getCost() + 0.20;}public function getIngredients() {return parent::getIngredients() . ", Sugar";} }// 使用裝飾器 $coffee = new SimpleCoffee(); echo "Cost: " . $coffee->getCost() . "\n"; echo "Ingredients: " . $coffee->getIngredients() . "\n";$coffeeWithMilk = new CoffeeWithMilk($coffee); echo "Cost: " . $coffeeWithMilk->getCost() . "\n"; echo "Ingredients: " . $coffeeWithMilk->getIngredients() . "\n";$coffeeWithSugar = new CoffeeWithSugar($coffeeWithMilk); echo "Cost: " . $coffeeWithSugar->getCost() . "\n"; echo "Ingredients: " . $coffeeWithSugar->getIngredients() . "\n";輸出結(jié)果: Cost: 1.99 Ingredients: Coffee Cost: 2.29 Ingredients: Coffee, Milk Cost: 2.79 Ingredients: Coffee, Milk, Milk, Sugar
在這個(gè)示例中,我們有一個(gè)Coffee接口和兩個(gè)實(shí)現(xiàn)了該接口的類:SimpleCoffee(被裝飾的對(duì)象)和CoffeeWithMilk、CoffeeWithSugar(裝飾器類)。
CoffeeWithMilk裝飾器類包裝了一個(gè)Coffee對(duì)象,并添加了牛奶和額外的成本。CoffeeWithSugar裝飾器類進(jìn)一步包裝了CoffeeWithMilk對(duì)象,并添加了糖和額外的成本。
通過鏈?zhǔn)绞褂醚b飾器,我們可以動(dòng)態(tài)地構(gòu)建具有不同功能和成本的咖啡。
迭代器模式
-
含義描述
迭代器設(shè)計(jì)模式允許你順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。通過使用迭代器,聚合對(duì)象與其迭代邏輯可以分離,從而使代碼更加靈活和可擴(kuò)展
-
應(yīng)用場景
- 操作鏈表、樹、圖:用迭代器模式可以讓集合類隱藏這些復(fù)雜性,只暴露“next”、“hasNext”等基本迭代操作,這樣既簡化了外部對(duì)集合元素的操作,也保護(hù)了集合的封裝性
- for、foreach循環(huán):通過for語句直接遍歷任何實(shí)現(xiàn)了迭代協(xié)議的對(duì)象,極大地簡化了遍歷過程,并且能夠利用生成器模式實(shí)現(xiàn)惰性計(jì)算和流式處理
-
代碼示例
//首先,定義一個(gè)迭代器接口(Iterator):interface Iterator {public function current();public function key();public function next();public function rewind();public function valid(); }//然后,定義一個(gè)具體的迭代器類(ConcreteIterator),它實(shí)現(xiàn)了迭代器接口:class ConcreteIterator implements Iterator {private $data;private $position = 0;public function __construct(array $data) {$this->data = $data;}public function current() {return $this->data[$this->position];}public function key() {return $this->position;}public function next() {$this->position++;}public function rewind() {$this->position = 0;}public function valid() {return isset($this->data[$this->position]);} }//接下來,定義一個(gè)聚合對(duì)象接口(Aggregate),該接口定義了一個(gè)方法來創(chuàng)建迭代器:interface Aggregate {public function createIterator(); }//然后,創(chuàng)建一個(gè)實(shí)現(xiàn)了聚合對(duì)象接口的具體聚合類(ConcreteAggregate):class ConcreteAggregate implements Aggregate {private $data = [];public function add($item) {$this->data[] = $item;}public function createIterator() {return new ConcreteIterator($this->data);} }//最后,你可以使用這些類來實(shí)現(xiàn)迭代器的功能:// 創(chuàng)建一個(gè)聚合對(duì)象 $aggregate = new ConcreteAggregate(); $aggregate->add('Element 1'); $aggregate->add('Element 2'); $aggregate->add('Element 3');// 獲取聚合對(duì)象的迭代器 $iterator = $aggregate->createIterator();// 使用迭代器遍歷聚合對(duì)象中的元素 $iterator->rewind(); while ($iterator->valid()) {echo $iterator->current() . "\n";$iterator->next(); }
在上面的示例中,ConcreteAggregate 類存儲(chǔ)了一個(gè)元素?cái)?shù)組,并提供了 createIterator() 方法來創(chuàng)建一個(gè)新的 ConcreteIterator 實(shí)例。ConcreteIterator 類實(shí)現(xiàn)了 Iterator 接口,用于遍歷 ConcreteAggregate 中的元素。