Principle: 介面隔離原則
情境:目前我們有一台全自動咖啡機
1 2 3 4 5 6 7 8 9 10 11
| <?php
namespace App\SOLID\ISP\CoffeeMachine\Contracts;
interface AutomaticCoffeeMachineInterface { public function grind($coffeeBeans);
public function brew($coffeePowder); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
use App\SOLID\ISP\CoffeeMachine\Contracts\AutomaticCoffeeMachineInterface;
class AutomaticCoffeeMachine implements AutomaticCoffeeMachineInterface { public function grind($coffeeBeans) { if ($coffeeBeans == '咖啡豆') { return '咖啡粉'; } }
public function brew($coffeePowder) { if ($coffeePowder == '咖啡粉') { 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 31 32 33 34 35 36 37
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
class Program { protected $coffeeGrinder;
protected $coffeeMaker;
public function getCoffeeByAutomaticCoffeeMachine($coffeeBeans) { $automaticCoffeeMachine = new AutomaticCoffeeMachine(); $this->coffeeGrinder = $automaticCoffeeMachine; $this->coffeeMaker = $automaticCoffeeMachine;
return $this->getCoffee($coffeeBeans); }
private function grind($coffeeBeans) { return $this->coffeeGrinder->grind($coffeeBeans); }
private function brew($coffeePowder) { return $this->coffeeMaker->brew($coffeePowder); }
private function getCoffee($coffeeBeans) { $coffeePowder = $this->grind($coffeeBeans); $coffee = $this->brew($coffeePowder); return $coffee; } }
|
然而,隨著對咖啡興趣增加,我們想來玩玩摩卡壺。
卻發現摩卡壺不會磨粉…
需求一:將全自動咖啡機介面職責分離,拆分出磨粉介面與沖煮介面
1 2 3 4 5 6 7 8 9
| <?php
namespace App\SOLID\ISP\CoffeeMachine\Contracts;
interface CoffeeGrinder { public function grind($coffeeBeans); }
|
1 2 3 4 5 6 7 8 9
| <?php
namespace App\SOLID\ISP\CoffeeMachine\Contracts;
interface CoffeeMaker { public function brew($coffeePowder); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeGrinder; use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeMaker;
class AutomaticCoffeeMachine implements CoffeeGrinder, CoffeeMaker { public function grind($coffeeBeans) { if ($coffeeBeans == '咖啡豆') { return '咖啡粉'; } }
public function brew($coffeePowder) { if ($coffeePowder == '咖啡粉') { return '咖啡'; } } }
|
需求二:實作磨豆機與摩卡壺
- 實作磨豆機(因為拆分出沖煮介面,它不需要知道如何沖煮)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeGrinder;
class NormalCoffeeGrinder implements CoffeeGrinder { public function grind($coffeeBeans) { if ($coffeeBeans == '咖啡豆') { return '咖啡粉'; } } }
|
- 實作摩卡壺(因為拆分出磨豆介面,它不需要知道如何磨豆)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeMaker;
class Mocalpot implements CoffeeMaker { public function brew($coffeePowder) { if ($coffeePowder == '咖啡粉') { 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| <?php
namespace App\SOLID\ISP\CoffeeMachine;
use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeGrinder; use App\SOLID\ISP\CoffeeMachine\Contracts\CoffeeMaker; use App\SOLID\ISP\CoffeeMachine\NormalCoffeeGrinder; use App\SOLID\ISP\CoffeeMachine\MocalPot;
class Program {
protected $coffeeGrinder;
protected $coffeeMaker;
public function getCoffeeByAutomaticCoffeeMachine($coffeeBeans) { $automaticCoffeeMachine = new AutomaticCoffeeMachine(); $this->setCoffeeGrinder($automaticCoffeeMachine); $this->setCoffeeMaker($automaticCoffeeMachine);
return $this->getCoffee($coffeeBeans); }
public function getCoffeeByNormalCoffeeGrinderAndMocalPot($coffeeBeans) { $normalCoffeeGrinder = new NormalCoffeeGrinder(); $mocalPot = new MocalPot(); $this->setCoffeeGrinder($normalCoffeeGrinder); $this->setCoffeeMaker($mocalPot);
return $this->getCoffee($coffeeBeans); }
private function grind($coffeeBeans) { return $this->coffeeGrinder->grind($coffeeBeans); }
private function brew($coffeePowder) { return $this->coffeeMaker->brew($coffeePowder); }
private function getCoffee($coffeeBeans) { $coffeePowder = $this->grind($coffeeBeans); $coffee = $this->brew($coffeePowder); return $coffee; }
private function setCoffeeGrinder(CoffeeGrinder $coffeeGrinder) { $this->coffeeGrinder = $coffeeGrinder; }
private function setCoffeeMaker(CoffeeMaker $coffeeMaker) { $this->coffeeMaker = $coffeeMaker; } }
|
ʕ •ᴥ•ʔ:運用介面隔離原則拆分介面職責,
我們就可以玩更多花樣的咖啡沖煮方法了。
而煮咖啡方法也不必因為器具更換而修改。
符合開放封閉原則。