1、常見的設計模式主要有23種,根據使用目標的不一樣能夠分爲如下三大類:建立設計模式、結構設計模式、行爲模式
建立設計模式: (5種)
用於建立對象時的設計模式.初始化對象流程的設計模式.當程序複雜時,須要靈活建立對象,同時減小建立時的依賴.建立設計模式就是解決此問題的一類設計模式.html
(1)單例模式
(2)工廠模式
(3)抽象工廠模式
(4)建造者模式
(5)原型模式算法
結構設計模式: (7種)
用於繼承和接口時的設計模式.結構設計模式用於新類的函數方法設計,減小沒必要要的類定義,減小代碼的冗餘.數據庫
(1)適配器模式
(2)橋接模式
(3)合成模式
(4)裝飾器模式
(5)門面模式
(6)代理模式
(7)享元模式設計模式
行爲模式: (11種)
用於方法實現以及對應算法的設計模式,同時也是最複雜的設計模式.行爲設計模式不只僅用於定義類的函數行爲,同時也用於不一樣類之間的協議、通訊.數組
(1)策略模式
(2)模板方法模式
(3)觀察者模式
(4)迭代器模式
(5)責任鏈模式
(6)命令模式
(7)備忘錄模式
(8)狀態模式
(9)訪問者模式
(10)中介者模式
(11)解釋器模式函數
2、按照範圍分爲: 類的設計模式,以及對象設計模式this
類的設計模式:用於類的具體實現的設計模式.包含了如何設計和定義類,以及父類和子類的設計模式.
對象設計模式: 用於對象的設計模式.與類的設計模式不一樣,對象設計模式主要用於運行期對象的狀態改變、動態行爲變動等.spa
3、設計模式六大原則設計
開放封閉原則: 一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉.
里氏替換原則: 全部引用基類的地方必須能透明地使用其子類的對象.
依賴倒置原則: 高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象.
單一職責原則: 不要存在多於一個致使類變動的緣由.通俗的說,即一個類只負責一項職責.
接口隔離原則: 客戶端不該該依賴它不須要的接口;一個類對另外一個類的依賴應該創建在最小的接口上.
迪米特法則: 一個對象應該對其餘對象保持最少的瞭解.
單例模式解決的是如何在整個項目中建立惟一對象實例的問題. (示例demo:)
1 <?php 2 //單例模式:保證某個類只有一個實例,能自行實例化對象,完成其全部的功能操做. 3 //最典型案例:數據庫操做(單例模式能夠避免大量的new操做.每一次new操做都會消耗系統和內存的資源.) 4 header("Content-Type: text/html;charset=utf-8"); 5 class User{ 6 //靜態的私有屬性(保存一個當前類的惟一對象) 7 private static $instance; 8 //私有的構造方法,防止類外new新對象 9 private function __construct(){ 10 } 11 //私有的克隆方法,防止類外克隆新對象 12 private function __clone(){ 13 14 } 15 //靜態的公開方法,獲得當前類的對象 16 public static function getInstance(){ 17 if(!self::$instance){ 18 self::$instance = new self(); 19 } 20 return self::$instance; 21 } 22 23 private $name; 24 public function setName($n){ 25 $this->name = $n; 26 } 27 public function getName(){ 28 echo $this->name; 29 } 30 31 } 32 $userA = User::getInstance(); 33 $userB = User::getInstance(); 34 echo '<pre>'.'單例模式獲取惟一實例:'.'<br>'; 35 var_dump($userA,$userB); 36 37 echo '<hr>'.'單例模式獲取當前類私有屬性:'.'<br>'; 38 $userA->setName('admin_a'); 39 $userB->setName('admin_b'); 40 $userA->getName(); 41 echo '<br>'; 42 $userB->getName();
運行結果以下圖:
工廠模式
工廠模式解決的是如何不經過new創建實例對象的方法. (示例demo)
1 <?php 2 //工廠模式:實例化對象模式,工廠方法代替new操做的一種設計模式. 3 //優勢:避免當改變某個類的名字或者方法以後,調用這個類的全部的代碼中都修改它的名字或者參數.(爲系統結構提供靈活的動態擴展機制,減小了耦合) 4 //簡單工廠模式生產對象 實例demo 5 interface People{ 6 public function sex(); 7 } 8 9 class Man implements People{ 10 public function sex(){ 11 echo 'this is Men'.'<br>'; 12 } 13 } 14 15 class Women implements People{ 16 public function sex(){ 17 echo 'this is Women'.'<br>'; 18 } 19 } 20 21 class Factoty{ 22 static function getObject($class_name){ 23 //可變類,生產新對象 24 return new $class_name; 25 } 26 } 27 28 $man = Factoty::getObject('Man'); 29 $man->sex(); 30 $woman = Factoty::getObject('Women'); 31 $woman->sex();
運行結果以下圖:
觀察者模式
當一個對象狀態發生變化時,依賴它的對象所有會收到通知,並自動更新. (示例demo)
1 <?php 2 //觀察者模式:某個對象能夠被設置爲是可觀察的,只要經過某種方式容許其餘對象註冊爲觀察者.每當被觀察的對象改變時,會發送信息給觀察者 3 4 //獲取類名和發送消息接口 5 interface IObserver{ 6 public function onSendMsg($msg); 7 public function getName(); 8 } 9 //添加可觀察者接口 10 interface IObservable{ 11 //注意:$observer是個對象,須要保存到數組中 12 public function addObserver($observer); 13 } 14 15 class UserList implements IObservable{ 16 private $_observers = array(); 17 //添加觀察者 18 public function addObserver($observer){ 19 $a=$this->_observers[]= $observer; 20 } 21 //移除觀察者 (注意:其實就是移除對應的類) 22 public function removeObserver($observer_name) { 23 foreach($this->_observers as $index => $observer) { 24 if ($observer->getName() === $observer_name) { 25 //從數組中移除選定的元素 26 return array_splice($this->_observers, $index, 1); 27 } 28 } 29 } 30 //發送消息 31 public function sendMsg($msg){ 32 foreach($this->_observers as $v){ 33 $v->onSendMsg($msg); 34 } 35 } 36 } 37 38 class OneObserver implements IObserver{ 39 public function onSendMsg($args){ 40 echo($args.'=> send to OneObserver<br>'); 41 } 42 public function getName(){ 43 return 'OneObserver'; 44 } 45 } 46 47 class TwoObserver implements IObserver{ 48 public function onSendMsg($args){ 49 echo($args.'=> send to TwoObserver<br>'); 50 } 51 public function getName(){ 52 return 'TwoObserver'; 53 } 54 } 55 56 $ul = new UserList();//被觀察者 57 $ul->addObserver(new OneObserver());//增長觀察者 58 $ul->addObserver(new TwoObserver());//增長觀察者 59 $ul->sendMsg('admin');//發送消息到觀察者 60 $ul->removeObserver('OneObserver');//移除觀察者 61 $ul->sendMsg("hello world");//發送消息到觀察者
運行結果以下圖:
策略模式
策略模式主要爲了讓客戶類可以更好地使用某些算法而不須要知道其具體的實現. (示例demo)
1 <?php 2 interface Strategy { //抽象策略角色,以接口實現 3 public function do_method(); //算法接口 4 } 5 6 class ConcreteStrategyA implements Strategy { //具體策略角色A 7 public function do_method() { 8 echo 'do method A'; 9 } 10 } 11 12 class ConcreteStrategyB implements Strategy { //具體策略角色B 13 public function do_method() { 14 echo 'do method B'; 15 } 16 } 17 18 class ConcreteStrategyC implements Strategy { //具體策略角色C 19 public function do_method() { 20 echo 'do method C'; 21 } 22 } 23 24 class Question{ //環境角色 25 private $_strategy; 26 //初始化Strategy接口對應實現類 27 public function __construct(Strategy $strategy) { 28 $this->_strategy = $strategy; 29 } 30 public function handle_question() { 31 $this->_strategy->do_method(); 32 } 33 } 34 35 $strategyA = new ConcreteStrategyA(); 36 $question = new Question($strategyA); 37 $question->handle_question();//輸出do method A 38 echo '<br>'; 39 $strategyB = new ConcreteStrategyB(); 40 $question = new Question($strategyB); 41 $question->handle_question();//輸出do method B 42 echo '<br>'; 43 $strategyC = new ConcreteStrategyC(); 44 $question = new Question($strategyC); 45 $question->handle_question();//輸出do method C
運行結果以下圖:
命令模式
命令模式:在軟件系統中,「行爲請求者」與「行爲實現者」一般呈現一種「緊耦合」。
但在某些場合,好比要對行爲進行「記錄、撤銷/重作、事務」等處理,這種沒法抵禦變化的緊耦合是不合適的。
在這種狀況下,如何將「行爲請求者」與「行爲實現者」解耦?將一組行爲抽象爲對象,實現兩者之間的鬆耦合。這就是命令模式。
角色分析:
抽象命令: 定義命令的接口,聲明執行的方法.
具體命令: 命令接口實現對象,是「虛」的實現;一般會持有接收者,並調用接收者的功能來完成命令要執行的操做.
命令接收者: 接收者,真正執行命令的對象.任何類均可能成爲一個接收者,只要它可以實現命令要求實現的相應功能.
控制者: 要求命令對象執行請求,一般會持有命令對象,能夠持有不少的命令對象.這個是客戶端真正觸發命令並要求命令執行相應操做的地方,也就是說至關於使用命令對象的入口. (示例demo)
1 <?php 2 interface Command { //命令角色 3 public function execute(); //執行方法 4 } 5 6 class ConcreteCommand implements Command { //具體命令方法 7 private $_receiver; 8 public function __construct(Receiver $receiver) { 9 $this->_receiver = $receiver; 10 } 11 //Command接口ConcreteCommand類實現對應Receiver類對應方法actionReceiver() 12 public function execute() { 13 $this->_receiver->actionReceiver(); 14 } 15 } 16 17 class Receiver { //接收者角色 18 private $_name; 19 public function __construct($name) { 20 $this->_name = $name; 21 } 22 public function actionReceiver() { 23 echo 'receive some cmd:'.$this->_name; 24 } 25 } 26 27 class Invoker { //請求者角色 28 private $_command; 29 public function __construct(Command $command) { 30 $this->_command = $command; 31 } 32 //Command接口ConcreteCommand類實現方法execute() 33 public function actionInvoker() { 34 $this->_command->execute(); 35 } 36 } 37 38 $receiver = new Receiver('hello world'); 39 $command = new ConcreteCommand($receiver); 40 $invoker = new Invoker($command); 41 $invoker->actionInvoker();//輸出:receive some cmd:hello world
運行結果以下圖: