思考:個人覺得我們沒有必要去死背硬記每一個模式,而是學會去理解什麼場景下應該用什麼模式,也就是說任何模式都是一個用來去解決某些場景來產生的方法思路。
一、簡單工廠模式(學習來源於git,供自己學習記憶)
1、使用場景:假如您正在蓋房子,那麼你需要門。您既可以選擇自己穿上木匠的衣服,帶些木頭,膠水,釘子和所有用來建造門的工具家中建造它,也可以直接致電工廠並把建造好的門交付給您,無需瞭解有關製作門的任何知識。
2、簡而言之:只需為客戶端生成一個例項,而無需向客戶端公開任何例項化邏輯
3、程式碼展現:
interface Door // 首先不管是什麼門,要有一個基本的門的定義介面
{
public function getWidth(): float;
public function getHeight(): float;
}
//然後我們定義一個木門,它實現了門這個介面,有高,有寬
class WoodenDoor implements Door
{
protected $width;
protected $height;
public function __construct(float $width, float $height)
{
$this->width = $width;
$this->height = $height;
}
public function getWidth(): float
{
return $this->width;
}
public function getHeight(): float
{
return $this->height;
}
}
// 第三步、創造一個工廠類,來按我們的門類進行創造門
class DoorFactory
{
// 這裡做一個解釋,為什麼在工廠類裡要寫一個makeDoor的方法呢,而不是直接去new WoodenDoor的方法呢,個人的理解是,一個工廠肯定不單單隻有造門一個功能,也可能會想要一個修改門的的功能,所以不通的功能單元用不同的方法是最好的實現方式
public static function makeDoor($width, $height): Door
{
return new WoodenDoor($width, $height);
}
}
// 第四步,就是我們通過呼叫工廠的製作門的方法來
// Make me a door of 100x200
$door = DoorFactory::makeDoor(100, 200);
echo 'Width: ' . $door->getWidth();
echo 'Height: ' . $door->getHeight();
// Make me a door of 50x100
$door2 = DoorFactory::makeDoor(50, 100);
4、總結:就是你要A,工廠給你例項化一個A,你要B,工廠給你例項化一個B。
二、工廠模式
1、場景:招聘經理招聘新員工。它不可能對每個職位進行面試。所以根據職位空缺,她必須決定面試步驟並將其委託給其他人。
2、簡而言之:它提供了一種將例項化邏輯委託給子類的方法。
3、程式碼實現:
// 第一步、實現一個面試官的介面,功能是提問題
interface Interviewer
{
public function askQuestions();
}
// 接下來是有兩個類分別實現該介面:
// 這個是開發者,是針對設計實現的類
class Developer implements Interviewer
{
public function askQuestions()
{
echo 'Asking about design patterns!';
}
}
// 這個類是針對社交建設實現的類
class CommunityExecutive implements Interviewer
{
public function askQuestions()
{
echo 'Asking about community building';
}
}
// 第二步是建立一個招聘經理的抽象類,它具有的功能是分配適合的面試官,並讓提問題(面試)
abstract class HiringManager
{
// Factory method
abstract protected function makeInterviewer(): Interviewer;
public function takeInterview()
{
$interviewer = $this->makeInterviewer(); //這裡的makeInterview()的作用在第三步可以看到,其實就是對其他類的物件建立(例項化)操作
$interviewer->askQuestions();
}
}
// 第三步、用不同的子類去繼承擴充套件這個抽象類
class DevelopmentManager extends HiringManager //開發管理者
{
protected function makeInterviewer(): Interviewer
{
return new Developer();
}
}
class MarketingManager extends HiringManager // 行政管理者
{
protected function makeInterviewer(): Interviewer
{
return new CommunityExecutive();
}
}
第四步、就是呼叫不同的類,進行實際的呼叫
$devManager = new DevelopmentManager();
$devManager->takeInterview(); // Output: Asking about design patterns
$marketingManager = new MarketingManager();
$marketingManager->takeInterview(); // Output: Asking about community building.
4、總結:我有一個總的工廠介面,假如有A和B兩個產品,那麼我就實現兩個子工廠,一個例項化A,一個例項化B,一個總工廠擁有多個子工廠,而子工廠和產品是一一對應的關係,即一個工廠只實現一種產品。
本作品採用《CC 協議》,轉載必須註明作者和本文連結