一、為什麼我要學習設計模式。
我的上一個項目是做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();
最後,設計模式是一種思想,不必生搬硬套,要不然只能適得其反。