PHP 流行設計模式示例(經過驗證)
《設計模式簡介》
設計模式:提供了一種廣泛的可重用的方式來解決我們日常程式設計中常常遇見的問題。設計模式並不一定就是一個類庫或者第三方框架,它們更多的表現為一種思想並且廣泛地應用在系統中。它們也表現為一種模式或者模板,可以在多個不同的場景下用於解決問題。設計模式可以用於加速開發,並且將很多大的想法或者設計以一種簡單地方式實現。當然,雖然設計模式在開發中很有作用,但是千萬要避免在不適當的場景誤用它們。
《設計模式分類》
根據目的和範圍,設計模式可以分為五類。
按照目的分為:建立設計模式,結構設計模式,以及行為設計模式。
按照範圍分為:類的設計模式,以及物件設計模式。
1. 按照目的分,目前常見的設計模式主要有23種,根據使用目標的不同可以分為以下三大類:
-
建立設計模式(Creational Patterns)(5種):用於建立物件時的設計模式。更具體一點,初始化物件流程的設計模式。當程式日益複雜時,需要更加靈活地建立物件,同時減少建立時的依賴。而建立設計模式就是解決此問題的一類設計模式。
- 單例模式【Singleton】
- 工廠模式【Factory】
- 抽象工廠模式【AbstractFactory】
- 建造者模式【Builder】
- 原型模式【Prototype】
-
結構設計模式(Structural Patterns)(7種):用於繼承和介面時的設計模式。結構設計模式用於新類的函式方法設計,減少不必要的類定義,減少程式碼的冗餘。
- 介面卡模式【Adapter】
- 橋接模式【Bridge】
- 合成模式【Composite】
- 裝飾器模式【Decorator】
- 門面模式【Facade】
- 代理模式【Proxy】
- 享元模式【Flyweight】
-
行為模式(Behavioral Patterns)(11種):用於方法實現以及對應演算法的設計模式,同時也是最複雜的設計模式。行為設計模式不僅僅用於定義類的函式行為,同時也用於不同類之間的協議、通訊。
- 策略模式【Strategy】
- 模板方法模式【TemplateMethod】
- 觀察者模式【Observer】
- 迭代器模式【Iterator】
- 責任鏈模式【ResponsibilityChain】
- 命令模式【Command】
- 備忘錄模式【Memento】
- 狀態模式【State】
- 訪問者模式【Visitor】
- 中介者模式【Mediator】
- 直譯器模式【Interpreter】
2.按照範圍分為:類的設計模式,以及物件設計模式
-
類的設計模式(Class patterns):用於類的具體實現的設計模式。包含了如何設計和定義類,以及父類和子類的設計模式。
-
物件設計模式(Object patterns): 用於物件的設計模式。與類的設計模式不同,物件設計模式主要用於執行期物件的狀態改變、動態行為變更等。
《設計模式六大原則》
1.單一職責
定義:不要存在多於一個導致類變更的原因。通俗的說,即一個類只負責一項職責。
優點:
1)、可以降低類的複雜度,一個類只負責一項職責,邏輯簡單;
2)、提高類的可讀性,提高系統的可維護性;
3)、變更引起的風險降低,變更是必然的。
2.里氏代換原則
定義:所有引用基類的地方必須能透明地使用其子類的物件,也就是說子類可以擴充套件父類的功能,但不能改變父類原有的功能
。
3.依賴倒置原則
定義:高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。
此處理解起來是最困難的,一般會在專案框架的搭建的時候用到,例如,業務邏輯層相對於資料層是高層模組,因為業務邏輯層需要呼叫資料層去連線資料庫,但是要做到可擴充套件高複用,儘量不要讓業務邏輯層依賴資料層,可以在資料層抽象出一個介面,讓業務邏輯層依賴於這個抽象介面。
優點:
1)、低層模組儘量都要有抽象類或介面,或者兩者都有。
2)、變數的宣告型別儘量是抽象類或介面。
3)、使用繼承時遵循里氏替換原則。
4.介面隔離原則
定義:客戶端不應該依賴它不需要的介面;一個類對另一個類的依賴應該建立在最小的介面上。
注意:
1)、介面儘量小,但是要有限度。對介面進行細化可以提高程式設計靈活性 是不掙的事實,但是如果過小,則會造成介面數量過多,使設計複雜化。所以一定要適度。
2)、為依賴介面的類定製服務,只暴露給呼叫的類它需要的方法,它不需要的方法則隱藏起來。只有專注地為一個模組提供定製服務,才能建立最小的依賴關係。
3)、提高內聚,減少對外互動。使介面用最少的方法去完成最多的事情。
5.迪米特法則(最少知道原則)
定義:一個物件應該對其他物件保持最少的瞭解。
簡單的理解就是高內聚,一個類的方法和屬效能用私有的就儘量私有化。
注意:
1)、只與直接的朋友通訊,不要和陌生人說話。
2)、過分的使用該原則,將導致系統複雜度變大。所以在採用迪米特法則時要反覆權衡,既做到結構清晰,又要高內聚低耦合。
6.開閉原則
定義:一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。
場景:在軟體的生命週期內,因為變化、升級和維護等原因需要對軟體原有程式碼進行修改時,可能會給舊程式碼中引入錯誤,也可能會使我們不得不對整個功能進行重構,並且需要原有程式碼經過重新測試。
建議:當軟體需求變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有的程式碼來實現變化。
《設計模式示例》
單例模式:
<?php
/**
* 單例模式類的屬性為final,防止被繼承
*/
/**
* singleton
* @author zhaosiwen1
*/
final class mysql
{
private static $instance; //單例
public $dbConn; //資料庫連線例項
private function __construct()
{
$this->dbConn = mysqli_connect('host','user','pwd','db');
}
/**
* 獲取類的例項化
* @return mysql
*/
public static function getInstance()
{
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 預防類被克隆
*/
private function __clone()
{
trigger_error('clone object is not allowed!');
}
}
$dbInstance = mysql::getInstance();
$flag = mysqli_query($dbInstance->dbConn,"select * from user200 where name = 'xza558n'");
$data = [];
while ($result = $flag->fetch_assoc()) {
$data[] = $result;
}
print_r($data);
結果如下圖: