設計模式 - 原型模式

悟空只要拔毛一吹,就能複製出千千萬萬個自己。

設計模式是解決開發時遇到普遍存在(反覆出現)的問題的各種解法。但並不是絕對的,遇到問題才使用解法而不是為了使用而使用

切記: 不要拿了錘子,看什麼都是釘子

介紹

屬於創建型設計模式,使你能夠復制已有對象, 而又無需使代碼依賴它們所屬的物件。

情境

我們以頻果為例,基本上頻果都是相同的物件,但會因為產地不同而有不同的起始價格。
而不同的時辰到貨,會有到貨日期上的差異。

範例

先以抽象類別來製作頻果的原型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
abstract class ApplePrototype {
/**
* @var string
*/
protected $category;

/**
* @var int
*/
protected $price;

/**
* @var int
*/
protected $count;

/**
* @var string
*/
protected $time;

abstract public function __clone();

/**
* @return int
*/
public function details(): string
{
return $this->category . ' 單價: ' . $this->price . ' 數量: ' . $this->count . ' 到貨時間: ' . $this->time;
}
}

實作頻果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Class Turnips.
*/
class Apples extends ApplePrototype
{
/**
* @var string
*/
protected $category = '頻果';

public function __construct(int $price, int $count)
{
$this->price = $price;
$this->count = $count;
$this->time = Date('Y-m-d');
}

public function __clone()
{
# 故意將日期 + 1 天,做出時間區隔
$this->time = Date('Y-m-d' ,strtotime('+1 day'));
}
}

分批兩天到貨,頻果資訊僅到貨日期會有區別

1
2
3
4
5
6
7
8
9
10
# 初始化頻果 100 元 40 顆。
$apple = new Apples(100, 40);

# 頻果到貨
echo $apple->details();
echo '<br />';

# 第二天的蘋果到貨
$apple2 = clone $apple;
echo $apple2->details();

結果

1
2
頻果 單價: 100 數量: 40 到貨時間: 2022-04-30
頻果 單價: 100 數量: 40 到貨時間: 2022-05-01

討論

原型模式著重於物件可以被複製,被複製出來的物件只有局部的內容不相同,用最節省資源的方式,來處理重複性質高的物件。

優點 :

  • 你可以克隆對象, 而無需與它們所屬的具體類相耦合。
  • 你可以克隆預生成原型, 避免反復運行初始化代碼。
  • 你可以更方便地生成復雜對象。
  • 你可以用繼承以外的方式來處理復雜對象的不同配置。

缺點:

  • 克隆包含循環引用的復雜對象可能會非常麻煩。
Author

LinYoYo

Posted on

2022-04-30

Updated on

2022-04-30

Licensed under