PHP中幾種常見的開發模式
這篇文章為大家帶來了關於PHP的相關知識,其中主要介紹了幾種常見的開發模式,下面一起來看一下,希望對大家有幫助。
設計模式六大原則
開放封閉原則:一個軟體實體如類別、模組和函數應該對擴充開放,對修改關閉。
里氏替換原則:所有引用基類的地方必須能透明地使用其子類的對象.
依賴倒置原則:高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽像不應該依賴細節;細節應該依賴抽象。
單一職責原則:不要存在多於一個導致類別變更的原因。通俗的說,即一個類只負責一項職責。
介面隔離原則:客戶端不應該依賴它不需要的介面;一個類別對另一個類別的依賴應該建立在最小的介面上。
迪米特法則:一個物件應該對其他物件保持最少的了解。
1.單例模式:
特點: 使用單例模式, 則可以避免大量的new 操作消耗的資源
單例類不能直接實例化創建,而是只能由類別本身實例化。因此,要獲得這樣的限制效果,建構函式必須標記為private,從而防止類別被實例化。
需要一個私人靜態成員變數來保存類別實例和公開一個能存取到實例的公開靜態方法。
在PHP中,為了防止他人對單例類別實例克隆,通常也為其提供一個空的私有__clone()方法。
$_instance必須宣告為靜態的私有變數
#建構子和析構函式必須宣告為私有,防止外部程式new 類別從而失去單例模式的意義
getInstance()方法必須設定為公有的,必須呼叫此方法以傳回實例的一個參考
::運算子只能存取靜態變數和靜態函數
new物件都會消耗記憶體
使用場景:最常用的地方是資料庫連接。
使用單例模式產生物件後, 該物件可以被其它眾多物件所使用。
私有的__clone()方法防止複製物件
<?php class Singleton{ //私有属性,用于保存实例 private static $instance; //构造方法私有化,防止外部创建实例 private function __construct(){}//公有方法,用于获取实例 public static function getInstance(){ //判断实例有无创建,没有的话创建实例并返回,有的话直接返回 if(!(self::$instance instanceof self)){ self::$instance = new self(); } return self::$instance; } //克隆方法私有化,防止复制实例 private function __clone(){}}
2.工廠模式
工廠模式,工廠方法或類別生成對象,而不是在程式碼中直接new。
使用方法 new實例化類,每次實例化只需呼叫工廠類別中的方法實例化即可。
優點:由於一個類別可能會在很多地方被實例化。當類別名稱或參數變更時,工廠模式可簡單快速的在工廠類別下的方法中一次性修改,避免了一個個的去修改實例化的物件
Test1.php
<?php class Test1 { static function test() { echo FILE; } }Factory.php <?php class Factory { /** *如果某个类在很多的文件中都new ClassName(),那么万一这个类的名字 *发生变更或者参数发生变化,如果不使用工厂模式,就需要修改每一个PHP *代码,使用了工厂模式之后,只需要修改工厂类或者方法就可以了。 */ static function createDatabase() { $test = new Test1(); return $test; } } Test.php <?php spl_autoload_register('autoload1'); $test = Factory::createDatabase(); $test->test();function autoload1($class) { $dir = __DIR__; $requireFile = $dir."\".$class.".php"; require $requireFile; }} Test1.php <?php class Test1 { protected static tt) { echo "对象已经创建<br>"; return self::tt = new Test1(); echo "创建对象<br>"; return self::$tt; } }function echoHello() { echo "Hello<br>"; }} Test.php <?php spl_autoload_register('autoload1'); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello();function autoload1($class) { $dir = __DIR__; $requireFile = $dir."\".$class.".php"; require $requireFile; }}
舉個例子,假設矩形、圓都有同樣的一個方法,那麼我們用基底類別提供的API來建立實例時,透過傳遞參數來自動建立對應的類別的實例,他們都有取得週長和面積的功能
<?php interface InterfaceShape { function getArea(); function getCircumference(); }/** • 矩形 */ class Rectangle implements InterfaceShape { private $width; private $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function getArea() { return $this->width* $this->height; } public function getCircumference() { return 2 * $this->width + 2 * $this->height; } }/** • 圆形 */ class Circle implements InterfaceShape { private $radius; function __construct($radius) { $this->radius = $radius; } public function getArea() { return M_PI * pow($this->radius, 2); } public function getCircumference() { return 2 * M_PI * $this->radius; } }/** • 形状工厂类 */ class FactoryShape { public static function create() { switch (func_num_args()) { case1: return newCircle(func_get_arg(0)); case2: return newRectangle(func_get_arg(0), func_get_arg(1)); default: # code... break; } } }rect); echo "<br>";// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) } circle);
3.註冊模式
註冊模式,解決全域共用和交換物件。已經創建好的對象,掛在到某個全域可以使用的數組上,在需要使用的時候,直接從該數組上獲取即可。將物件註冊到全域的樹上。任何地方直接去訪問。
<?php class Register { protected static $objects;//将对象注册到全局的树上 function set($alias,$object) { self::$objects[$alias] = $object;//将对象放到树上 } static function get($name) { return self::$objects[$name];//获取某个注册到树上的对象 } function _unset($alias) { unset(self::$objects[$alias]);//移除某个注册到树上的对象。 }}
4.策略模式
策略模式,將一組特定的行為和演算法封裝成類,以適應某些特定的上下文環境。
eg:如果有一個電商網站系統,針對男性女性使用者要各自跳到不同的商品類目,並且所有的廣告位展示不同的廣告。在傳統的代碼中,都是在系統中加入各種if else的判斷,硬編碼的方式。如果有一天增加了一種用戶,就需要改寫程式碼。使用策略模式,如果新增加一種使用者類型,只需要增加一種策略就可以。其他所有的地方只需要使用不同的策略就可以。
首先聲明策略的介面文件,約定了策略的包含的行為。然後,定義各個特定的策略實作類別。
UserStrategy.php
<?php /*• 声明策略文件的接口,约定策略包含的行为 */interface UserStrategy { function showAd(); function showCategory(); }FemaleUser.php <?phprequire_once 'Loader.php'; class FemaleUser implements UserStrategy { function showAd() { echo "2016冬季女装"; }function showCategory(){ echo "女装"; }} MaleUser.php <?phprequire_once 'Loader.php'; class MaleUser implements UserStrategy { function showAd(){ echo "IPhone6s"; }function showCategory(){ echo "电子产品"; }} Page.php//执行文件 <?php require_once 'Loader.php'; class Page { protected $strategy;function index(){ echo "AD"; $this->strategy->showAd(); echo "<br>"; echo "Category"; $this->strategy->showCategory(); echo "<br>"; } function setStrategy(UserStrategy $strategy){ $this->strategy = $strategy; }} $page = new Page(); if(isset($_GET['male'])){ $strategy = new MaleUser(); }else { $strategy = new FemaleUser(); }strategy); $page->index();
總結:
透過以上方式,可以發現,在不同使用者登入時顯示不同的內容,但是解決了在顯示時的硬編碼的問題。如果要增加一種策略,只需要增加一種策略實作類別,然後在入口檔案中執行判斷,傳入這個類別即可。實作了解耦。實作依賴倒置和控制反轉 (有待理解); 透過介面的方式,使得類別和類別之間不直接依賴。在使用該類別的時候,才動態的傳入該介面的實作類別。如果要替換某個類,只需要提供一個實作了該介面的實作類,透過修改一行程式碼即可完成替換。
5.观察者模式
观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新(一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者)
场景1:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
场景2: 用户登录,需要写日志,送积分,参与活动等;使用消息队列,把用户和日志,积分,活动之间解耦合
观察者模式实现了低耦合,非侵入式的通知与更新机制。
<?php /* 观察者接口 */ interface InterfaceObserver { function onListen($sender, $args); function getObserverName(); }// 可被观察者接口 interface InterfaceObservable { function addObserver(observer_name); }// 观察者抽象类 abstract class Observer implements InterfaceObserver { protected $observer_name;function getObserverName() { return $this->observer_name; }function onListen($sender, $args) {} }// 可被观察类 abstract class Observable implements InterfaceObservable { protected $observers = array();public function addObserver(observerinstanceofInterfaceObserver) { $this->observers[] = $observer; } }public function removeObserver(this->observersas $index => observer->getObserverName() === this->observers, $index, 1); return; } } } }// 模拟一个可以被观察的类 class A extends Observable { public function addListener(this->observersas $observer) { this, $listener); } } }// 模拟一个观察者类 class B extends Observer { protected $observer_name = 'B';public function onListen($sender, sender); echo "<br>"; var_dump($args); echo "<br>"; } }// 模拟另外一个观察者类 class C extends Observer { protected $observer_name = 'C';public function onListen($sender, sender); echo "<br>"; var_dump($args); echo "<br>"; } }a->addObserver(new B()); $a->addObserver(new C());// 可以看到观察到的信息 $a->addListener('D');// 移除观察者 $a->removeObserver('B');// 打印的信息: // object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } } // string(1) "D" // object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } } // string(1) "D"
6.装饰器模式
装饰器模式, 根据运行时不同的情景动态地为某个对象调用前后添加不同的行
一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重写实现类的方法,使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大额灵活性
场景:
1.symfony 控制器中beforepost afterpost 中post提交前和提交后,对数据处理
2.当某一功能或方法draw,要满足不同的功能需求时,可以使用装饰器模式
/** • 输出一个字符串 • 装饰器动态添加功能 • Class EchoText */ class EchoText { protected $decorator = []; public function Index() { //调用装饰器前置操作 $this->beforeEcho(); echo "你好,我是装饰器。"; //调用装饰器后置操作 $this->afterEcho(); } //增加装饰器 public function addDecorator(Decorator $decorator) { $this->decorator[] = $decorator; } //执行装饰器前置操作 先进先出原则 protected function beforeEcho() { foreach ($this->decorator as $decorator) $decorator->before(); } //执行装饰器后置操作 先进后出原则 protected function afterEcho() { this->decorator); foreach ($tmp as $decorator) $decorator->after(); } }/** • 装饰器接口 • Class Decorator */ interface Decorator { public function before(); public function after(); }/** • 颜色装饰器实现 • Class ColorDecorator */ class ColorDecorator implements Decorator { protected $color; public function __construct($color) { $this->color = $color; } public function before() { echo "<dis style='color: {$this->color}'>"; } public function after() { echo "</div>"; } }/** • 字体大小装饰器实现 • Class SizeDecorator */ class SizeDecorator implements Decorator { protected $size; public function __construct($size) { $this->size = $size; } public function before() { echo "<dis style='font-size: {$this->size}px'>"; } public function after() { echo "</div>"; } }//实例化输出类 echo->addDecorator(new ColorDecorator('red')); //增加装饰器 echo->Index(); //输出<dis style='color: red'><dis style='font-size: 22px'>你好,我是装饰器。</div></div>
7.适配器模式
将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,,mysqli,pdo,可以用适配器统一
//老的代码 class User {private $name; function __construct($name) { $this->name = $name; } public function getName() { return $this->name; }} //新代码,开放平台标准接口 interface UserInterface { function getUserName(); }class UserInfo implements UserInterface { protected $user; function __construct($user) { $this->user = $user; } public function getUserName() { return $this->user->getName(); }} $olduser = new User('张三'); echo $olduser->getName()."n";olduser); echo $newuser->getUserName()."n";
推荐学习:《PHP视频教程》
以上是PHP中幾種常見的開發模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

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

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
