範例:自助餐餐廳 (外觀模式)

Pattern: 外觀模式

Class Diagram: 自助餐餐廳


情境:以下是某自助餐餐廳的情況

  • 自助式霜淇淋機
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
<?php

namespace App\FacadePattern\Buffet;

class IceCreamMachine
{
public function addIngredients()
{
//倒入牛奶、糖、鮮奶油、蛋黃等
return $this;
}

public function stir()
{
//攪拌均勻
return $this;
}

public function chill()
{
//使其冷藏
return $this;
}

public function squeeze()
{
//擠出霜淇淋
return '霜淇淋';
}
}
  • 自助式咖啡機
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
<?php

namespace App\FacadePattern\Buffet;

class CoffeeMachine
{
public function addCoffeeBeans()
{
//放入咖啡豆
return $this;
}

public function grind()
{
//研磨咖啡豆
return $this;
}

public function brew()
{
//沖煮咖啡
return $this;
}

public function stirWithMilk()
{
//與牛奶攪拌
return '拿鐵';
}
}

老闆認為目前的方式,客人必須知道霜淇淋機與咖啡機所有的操作流程。

不是那麼地友好,希望我們能寫個簡單的介面,讓客人更容易取得餐點。


需求一:替霜淇淋機與咖啡機設計簡單的介面,方便取用

  • 霜淇淋機的簡單介面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\FacadePattern\Buffet\Facade;

use App\FacadePattern\Buffet\IceCreamMachine;

class IceCreamMachineFacade
{
public static function makeIceCream()
{
$iceCreamMachine = new IceCreamMachine();

return $iceCreamMachine
->addIngredients()
->stir()
->chill()
->squeeze();
}
}
  • 咖啡機的簡單介面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\FacadePattern\Buffet\Facade;

use App\FacadePattern\Buffet\CoffeeMachine;

class CoffeeMachineFacade
{
public static function makeLatte()
{
$coffeeMachine = new CoffeeMachine();

return $coffeeMachine
->addCoffeeBeans()
->grind()
->brew()
->stirWithMilk();
}
}
  • 最後修改客人的點餐程式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\FacadePattern\Buffet;

use App\FacadePattern\Buffet\Facade\CoffeeMachineFacade;
use App\FacadePattern\Buffet\Facade\IceCreamMachineFacade;

class Program
{
public function makeIceCream()
{
return IceCreamMachineFacade::makeIceCream();
}

public function makeLatte()
{
return CoffeeMachineFacade::makeLatte();
}
}

這下子,客人終於不用知道太多,便能取得自己想要的餐點了。


[單一職責原則]
我們將子類別接口類別視作兩種不同的職責。

[開放封閉原則]
對於客戶端與接口類別來說,並不會因為我們用了新的咖啡機而有所區別。

然而當子類別改動時可能會連帶修改到接口類別。

ʕ •ᴥ•ʔ:在這個例子中,我會覺得是霜淇淋機/咖啡機不對,
竟然沒有提供簡單的介面!