一、為什麼我要學習設計模式。
我的上一個項目是做App接口,由於時間緊,老板催的急,所以到最後項目完工時發現居然寫了幾萬行代碼,可想而知代碼質量有多糟糕。而且很多時候,調用接口的開發人員來找我說某個接口出錯了,我回去調試一看才發現果然粗心寫錯一句代碼,然而有六七個控制器裡面我都有同樣的語句,這就造成了我要回去查找那六七個文件,然後挨個修改。這下就傻眼,突然發現我真的應該看看設計模式了,這樣可以提高代碼質量,客戶修改需求的時候也不至於讓自己咬牙切齒(大家應該都有這種體會,哈哈);
二、策略模式
1.概念
策略模式:定義了算法族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。(概念太難理解)
2.為什麼會有策略模式
joe上班的公司做了一套模擬鴨子的游戲,游戲中會出現各種鴨子,有的會呱呱叫,有的會飛。
代碼:
1 <?php 2 class Duck { 3 public function quack(){} 4 public function swim(){} 5 public function display(){}
public function fly(){
//會飛了
} 6 //鴨子的其他方法 7 } 8 9 class MallarDuck extends Duck{ 10 public function display(){ 11 //外觀是綠頭 12 } 13 } 14 class RedDuck extends Duck{ 15 public function display(){ 16 //外觀是紅頭 17 } 18 }
這樣繼承了Duck類的子類都可以實現飛行行為,但是如果玩具鴨就不能有飛行行為的話不是鬧笑話了麼? 有的人會說,我可以在子類裡面重寫父類的fly方法,這樣就可以針對不同的具體子類給予不同的行為。但是這樣的話,不是重復很多代碼了嗎?相信大家會直接copy,這樣如果某一個地方出錯,所有地方都要重新更改,而且老板隨時改變需求,我們會被直接累趴。
所以設計模式裡的原則來了:
1.找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。
2.針對接口編程,而不是針對實現編程。
3.多用組合,少用繼承。
三、具體代碼
<?php abstract class Duck { public $flyBehavior; //飛行行為 public $quackBehavior; //叫行為 public function swim(){ echo '鴨子會游泳'; } public function performQuack(){ $this->quackBehavior->quack(); } public function performFly(){ $this->flyBehavior->fly(); } public function setFlyBehavior(FlyBehavior $fb){ $this->flyBehavior = $fb; } public function setQuackBehavior(QuackBehavior $qb){ $this->quackBehavior = $qb; } abstract function display(); } interface FlyBehavior { public function fly(); } class FlyWithWings implements FlyBehavior{ public function fly(){ echo '會飛'; } } class FlyNoWay implements FlyBehavior { public function fly(){ echo '不會飛'; } } interface QuackBehavior { public function quack(); } class Quackd implements QuackBehavior { public function quack(){ echo '呱呱叫'; } } class Squeak implements QuackBehavior { public function quack(){ echo '吱吱叫'; } } class MuteQuack implements QuackBehavior { public function quack(){ echo '不會叫'; } } /** * 模型鴨類 */ class ModelDuck extends Duck { public function __construct() { $this->flyBehavior = new FlyNoWay(); $this->quackBehavior = new Quackd(); } public function display() { echo '模型鴨'; } } //測試代碼 $m = new ModelDuck(); $m->display(); $m->performQuack(); $m->performFly(); $m->setFlyBehavior(new FlyWithWings()); $m->performFly();
最後,設計模式是一種思想,不必生搬硬套,要不然只能適得其反。