Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure which it inherits from the parent class.
abstract class Burger { final public function make() { return $this->layBread() ->spreadSauce() ->addLettuce() ->addPrimaryToppings(); } protected function layBread() { var_dump('lay bread'); return $this; } protected function spreadSauce() { var_dump('spread Sauce'); return $this; } protected function addLettuce() { var_dump('add lettuce'); return $this; } protected abstract function addPrimaryToppings(); }
Now, subclass extending Burger can add its own implementation for addPrimaryToppings()
.
class ChickenBurger extends Burger { protected function addPrimaryToppings() { var_dump('add chicken'); return $this; } }
class VeggieBurger extends Burger{ protected function addPrimaryToppings() { var_dump('add veggie'); return $this; } }
class ChickenBurger { public function make() { return $this->layBread() ->spreadSauce() ->addLettuce() ->addChicken(); } public function layBread() { var_dump('lay bread'); return $this; } public function spreadSauce() { var_dump('spread Sauce'); return $this; } public function addLettuce() { var_dump('add lettuce'); return $this; } public function addChicken() { var_dump('add chicken'); return $this; } }
To make another burger, say Veggie Burger, we need to copy many similar functions from the ChickenBurger Class.
class VeggieBurger { public function make() { return $this->layBread() ->spreadSauce() ->addLettuce() ->addVeggie(); } public function layBread() { var_dump('lay bread'); return $this; } public function spreadSauce() { var_dump('spread Sauce'); return $this; } public function addLettuce() { var_dump('add lettuce'); return $this; } public function addLettuce() { var_dump('add veggie'); return $this; } }