'Head First design patterns' code PHP version of object oriented learning

  • 2020-03-31 20:51:55
  • OfStack

The examples in the book are relatively easy to understand, but as they are written by foreigners, the habits of the examples are not very Chinese, which may look a little strange occasionally, and the language habits are not Chinese. Of course the & # 65533; The & # 65533; After reading this book, you can gain insight into what design patterns can and cannot solve for you (such as not replacing your coding).
I changed some of the code in the book to PHP. It should be easy to understand the concept of code and cooperation.

The strategy pattern
 
<?php 
 
//Flight behavior interface
interface FlyBehavior { 
public function fly(); 
} 
//It's a behavior interface
interface QuackBehavior { 
public function quack(); 
} 
//Wings to fly
class FlyWithWings implements FlyBehavior { 
public function fly() { 
echo "I'm flying!!n"; 
} 
} 
//Can't fly
class FlyNoWay implements FlyBehavior { 
public function fly() { 
echo "I can't fly!n"; 
} 
} 
class FlyRocketPowered implements FlyBehavior { 
public function fly() { 
echo "I'm flying with a rocket!n"; 
} 
} 
class Qquack implements QuackBehavior { 
public function quack() { 
echo "Quackn"; 
} 
} 
class Squeak implements QuackBehavior { 
public function quack() { 
echo "Squeakn"; 
} 
} 
class MuteQuack implements QuackBehavior { 
public function quack() { 
echo "<< Silence >>n"; 
} 
} 
abstract class Duck { 
protected $quack_obj; 
protected $fly_obj; 
public abstract function display(); 

public function performQuack() { 
$this->quack_obj->quack(); 
} 
public function performFly() { 
$this->fly_obj->fly(); 
} 
public function swim() { 
echo "All ducks float, even decoys!n"; 
} 
public function setFlyBehavior(FlyBehavior $fb) { 
$this->fly_obj = $fb; 
} 
public function setQuackBehavior(QuackBehavior $qb) { 
$this->quack_obj = $qb; 
} 
} 

class ModelDuck extends Duck { 
public function __construct() { 
$this->fly_obj = new FlyNoWay(); 
$this->quack_obj = new MuteQuack(); 
} 
public function display() { 
echo "I'm a model duck!n"; 
} 
} 

$model = new ModelDuck(); 
$model->performFly(); 
$model->performQuack(); 
//Provide new capabilities
$model->setFlyBehavior(new FlyRocketPowered()); 
$model->setQuackBehavior(new Squeak()); 
$model->performFly(); 
$model->performQuack(); 

?> 

A singleton
 
<?php 
 
class MyClass { 
private static $uniqueInstance; 
private function __construct() { 

} 
public static function getInstance() { 
if (self::$uniqueInstance == null) { 
self::$uniqueInstance = new MyClass(); 
} 
return self::$uniqueInstance; 
} 
} 
$myClass = MyClass::getInstance(); 
var_dump($myClass); 
$myClass = MyClass::getInstance(); 
var_dump($myClass); 
?> 

Factory method model
 
<?php 
abstract class PizzaStore { 
public function orderPizza($type) { 
$pizza = $this->createPizza($type); 

$pizza->prepare(); 
$pizza->bake(); 
$pizza->cut(); 
$pizza->box(); 
return $pizza; 
} 

public abstract function createPizza($type); 
} 
class NYPizzaStore extends PizzaStore { 
public function createPizza($type) { 
if ($type == "cheese") { 
return new NYStyleCheesePizza(); 
} elseif ($type == "veggie") { 
return new NYStyleVeggiePizza(); 
} elseif ($type == "clam") { 
return new NYStyleClamPizza(); 
} elseif ($type == "papperoni") { 
return new NYStylePapperoniPizza(); 
} else { 
return null; 

} 
} 
} 
class ChicagoPizzaStore extends PizzaStore { 
public function createPizza($type) { 
if ($type == "cheese") { 
return new ChicagoStyleCheesePizza(); 
} elseif ($type == "veggie") { 
return new ChicagoStyleVeggiePizza(); 
} elseif ($type == "clam") { 
return new ChicagoStyleClamPizza(); 
} elseif ($type == "papperoni") { 
return new ChicagoStylePapperoniPizza(); 
} else { 
return null; 
} 
} 
} 
abstract class Pizza { 
public $name; 
public $dough; 
public $sauce; 
public $toppings = array(); 

public function prepare() { 
echo "Preparing " . $this->name . "n"; 
echo "Yossing dough...n"; 
echo "Adding sauce...n"; 
echo "Adding toppings: n"; 
for ($i = 0; $i < count($this->toppings); $i++) { 
echo " " . $this->toppings[$i] . "n"; 
} 
} 

public function bake() { 
echo "Bake for 25 minutes at 350n"; 
} 

public function cut() { 
echo "Cutting the pizza into diagonal slicesn"; 
} 

public function box() { 
echo "Place pizza in official PizzaStore boxn"; 
} 

public function getName() { 
return $this->name; 
} 
} 

class NYStyleCheesePizza extends Pizza { 
public function __construct() { 
$this->name = "NY Style Sauce and cheese Pizza"; 
$this->dough = "Thin Crust Dough"; 
$this->sauce = "Marinara Sauce"; 

$this->toppings[] = "Grated Reggiano Cheese"; 
} 
} 

class NYStyleVeggiePizza extends Pizza { 
public function __construct() { 
$this->name = "NY Style Sauce and veggie Pizza"; 
$this->dough = "Thin Crust Dough"; 
$this->sauce = "Marinara Sauce"; 

$this->toppings[] = "Grated Reggiano veggie"; 
} 
} 
class NYStyleClamPizza extends Pizza { 
public function __construct() { 
$this->name = "NY Style Sauce and clam Pizza"; 
$this->dough = "Thin Crust Dough"; 
$this->sauce = "Marinara Sauce"; 

$this->toppings[] = "Grated Reggiano clam"; 
} 
} 
class NYStylePapperoniPizza extends Pizza { 
public function __construct() { 
$this->name = "NY Style Sauce and papperoni Pizza"; 
$this->dough = "Thin Crust Dough"; 
$this->sauce = "Marinara Sauce"; 

$this->toppings[] = "Grated Reggiano papperoni"; 
} 
} 

class ChicagoStyleCheesePizza extends Pizza { 
public function __construct() { 
$this->name = "Chicago Style Deep Dish Cheese Pizza"; 
$this->dough = "Extra Thick Crust Dough"; 
$this->sauce = "Plum Tomato Sauce"; 

$this->toppings[] = "Shredded Mozzarella Cheese"; 
} 

public function cut() { 
echo "Cutting the pizza into square slicesn"; 
} 
} 

$myStore = new NYPizzaStore(); 
$chicagoStore = new ChicagoPizzaStore(); 
$pizza = $myStore->orderPizza("cheese"); 
echo "Ethan ordered a " . $pizza->getName() . "n"; 

$pizza = $chicagoStore->orderPizza("cheese"); 
echo "Ethan ordered a " . $pizza->getName() . "n"; 

?> 

The factory pattern
 
<?php 
abstract class PizzaStore { 
public function orderPizza($type) { 
$pizza = $this->createPizza($type); 

$pizza->prepare(); 
$pizza->bake(); 
$pizza->cut(); 
$pizza->box(); 
return $pizza; 
} 

public abstract function createPizza($type); 
} 
class NYPizzaStore extends PizzaStore { 
public function createPizza($type) { 
$pizza = null; 
$ingredientFactory = new NYPizzaIngredientFactory(); 
if ($type == "cheese") { 
$pizza = new CheesePizza($ingredientFactory); 
$pizza->setName('New York Style Cheese Pizza'); 
} elseif ($type == "veggie") { 
$pizza = new VeggiePizza($ingredientFactory); 
$pizza->setName('New York Style Veggie Pizza'); 
} elseif ($type == "clam") { 
$pizza = new ClamPizza($ingredientFactory); 
$pizza->setName('New York Style Clam Pizza'); 
} elseif ($type == "papperoni") { 
$pizza = new PapperoniPizza($ingredientFactory); 
$pizza->setName('New York Style Papperoni Pizza'); 
} 
return $pizza; 
} 
} 
class ChicagoPizzaStore extends PizzaStore { 
public function createPizza($type) { 
if ($type == "cheese") { 
return new ChicagoStyleCheesePizza(); 
} elseif ($type == "veggie") { 
return new ChicagoStyleVeggiePizza(); 
} elseif ($type == "clam") { 
return new ChicagoStyleClamPizza(); 
} elseif ($type == "papperoni") { 
return new ChicagoStylePapperoniPizza(); 
} else { 
return null; 
} 
} 
} 
interface PizzaIngredientFactory { 
public function createDough(); 
public function createSauce(); 
public function createCheese(); 
public function createVeggies(); 
public function createPepperoni(); 
public function createClam(); 
} 
class NYPizzaIngredientFactory implements PizzaIngredientFactory { 
public function createDough() { 
return new ThinCrustDough(); 
} 
public function createSauce() { 
return new MarinaraSauce(); 
} 
public function createCheese() { 
return new ReggianoCheese(); 
} 
public function createVeggies() { 
$veggies = array( 
new Garlic(), 
new Onion(), 
new Mushroom(), 
new RedPepper(), 
); 
return $veggies; 
} 
public function createPepperoni() { 
return new SlicedPepperoni(); 
} 
public function createClam() { 
return new FreshClams(); 
} 
} 
class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { 
public function createDough() { 
return new ThickCrustDough(); 
} 
public function createSauce() { 
return new PlumTomatoSauce(); 
} 
public function createCheese() { 
return new Mozzarella(); 
} 
public function createVeggies() { 
$veggies = array( 
new BlackOlives(), 
new Spinach(), 
new EggPlant(), 
); 
return $veggies; 
} 
public function createPepperoni() { 
return new SlicedPepperoni(); 
} 
public function createClam() { 
return new FrozenClams(); 
} 
} 
abstract class Pizza { 
public $name; 
public $dough; 
public $sauce; 
public $veggies = array(); 
public $cheese; 
public $pepperoni; 
public $clam; 

public abstract function prepare(); 

public function bake() { 
echo "Bake for 25 minutes at 350n"; 
} 

public function cut() { 
echo "Cutting the pizza into diagonal slicesn"; 
} 

public function box() { 
echo "Place pizza in official PizzaStore boxn"; 
} 

public function getName() { 
return $this->name; 
} 

public function setName($name) { 
$this->name = $name; 
} 

public function __toString() { 

} 
} 

class CheesePizza extends Pizza { 
public $ingredientFactory; 

public function __construct(PizzaIngredientFactory $ingredientFactory) { 
$this->ingredientFactory = $ingredientFactory; 
} 

public function prepare() { 
echo "Preparing " . $this->name . "n"; 
$this->dough = $this->ingredientFactory->createDough(); 
$this->sauce = $this->ingredientFactory->createSauce(); 
$this->cheese = $this->ingredientFactory->createCheese(); 
} 
} 

class ClamPizza extends Pizza { 
public $ingredientFactory; 

public function __construct(PizzaIngredientFactory $ingredientFactory) { 
$this->ingredientFactory = $ingredientFactory; 
} 

public function prepare() { 
echo "Preparing " . $this->name . "n"; 
$this->dough = $this->ingredientFactory->createDough(); 
$this->sauce = $this->ingredientFactory->createSauce(); 
$this->cheese = $this->ingredientFactory->createCheese(); 
$clam = $this->ingredientFactory->createClam(); 
} 
} 

$nyPizzaStore = new NYPizzaStore(); 
$nyPizzaStore->orderPizza('cheese'); 
?> 




Observer mode
 
<?php 
 
interface Subject { 
public function registerObserver(Observer $o); 
public function removeObserver(Observer $o); 
public function notifyObservers(); 
} 
interface Observer { 
public function update($temperature, $humidity, $pressure); 
} 
interface DisplayElement { 
public function display(); 
} 
class WeatherData implements Subject { 
private $observers = array(); 
private $temperature; 
private $humidity; 
private $pressure; 
public function __construct() { 
$this->observers = array(); 
} 
public function registerObserver(Observer $o) { 
$this->observers[] = $o; 
} 
public function removeObserver(Observer $o) { 
if (($key = array_search($o, $this->observers)) !== false) { 
unset($this->observers[$key]); 
} 
} 
public function notifyObservers() { 
foreach ($this->observers as $observer) { 
$observer->update($this->temperature, $this->humidity, $this->pressure); 
} 
} 
public function measurementsChanged() { 
$this->notifyObservers(); 
} 
public function setMeasurements($temperature, $humidity, $pressure) { 
$this->temperature = $temperature; 
$this->humidity = $humidity; 
$this->pressure = $pressure; 
$this->measurementsChanged(); 
} 
} 
class CurrentConditionsDisplay implements Observer, DisplayElement { 
private $temperature; 
private $humidity; 
private $weatherData; 
public function __construct(Subject $weatherData) { 
$this->weatherData = $weatherData; 
$weatherData->registerObserver($this); 
} 
public function update($temperature, $humidity, $pressure) { 
$this->temperature = $temperature; 
$this->humidity = $humidity; 
$this->display(); 
} 
public function display() { 
echo " Temperature: " . $this->temperature . ";  Humidity: " . $this->humidity . "%n"; 
} 
} 
class StatistionsDisplay implements Observer, DisplayElement { 
private $temperature; 
private $humidity; 
private $pressure; 
private $weatherData; 
public function __construct(Subject $weatherData) { 
$this->weatherData = $weatherData; 
$weatherData->registerObserver($this); 
} 
public function update($temperature, $humidity, $pressure) { 
$this->temperature = $temperature; 
$this->humidity = $humidity; 
$this->pressure = $pressure; 
$this->display(); 
} 
public function display() { 
echo " Temperature: " . $this->temperature . ";  Humidity: " . $this->humidity . "%;  Pressure: " . $this->pressure . "n"; 
} 
} 
$weatherData = new WeatherData(); 
$currentDisplay = new CurrentConditionsDisplay($weatherData); 
$statistionDisplay = new StatistionsDisplay($weatherData); 
$weatherData->setMeasurements(10, 20, 30); 
$weatherData->removeObserver($currentDisplay); 
$weatherData->setMeasurements(30, 40, 50); 
?> 

Command mode
 
<?php 

class Light { 
public function __construct() { 

} 

public function on() { 
echo "Light Onn"; 
} 

public function off() { 
echo "Light Offn"; 
} 
} 

interface Command { 
public function execute(); 
} 

class LightOnCommand implements Command { 
public $light; 

public function __construct(Light $light) { 
$this->light = $light; 
} 

public function execute() { 
$this->light->on(); 
} 
} 

class SimpleRemoteControl { 
public $slot; 

public function __construct() { 

} 

public function setCommand(Command $command) { 
$this->slot = $command; 
} 

public function buttonWasPressed() { 
$this->slot->execute(); 
} 
} 

class RemoteControlTest { 
public static function main() { 
$remote = new SimpleRemoteControl(); 
$light = new Light(); 
$lightOn = new LightOnCommand($light); 
$remote->setCommand($lightOn); 
$remote->buttonWasPressed(); 
} 
} 

RemoteControlTest::main(); 

?> 

Decorator mode
 
<?php 
 
abstract class Beverage { 
public $description = "Unknown Beverage"; 

public function getDescription() { 
return $this->description; 
} 

public abstract function cost(); 
} 

abstract class CondimentDecorator extends Beverage { 
//This is an abstract class in JAVA code, which PHP doesn't allow
public function getDescription() { 
return $this->description; 
} 
} 

class Espresso extends Beverage { 
public function __construct() { 
$this->description = "Espresso"; 
} 

public function cost() { 
return 1.99; 
} 
} 

class HouseBlend extends Beverage { 
public function __construct() { 
$this->description = "HouseBlend"; 
} 

public function cost() { 
return .89; 
} 
} 

class DarkRoast extends Beverage { 
public function __construct() { 
$this->description = "DarkRoast"; 
} 

public function cost() { 
return .99; 
} 
} 

class Mocha extends CondimentDecorator { 
public $beverage; 

public function __construct(Beverage $beverage) { 
$this->beverage = $beverage; 
} 
public function getDescription() { 
return $this->beverage->getDescription() . ", Mocha"; 
} 
public function cost() { 
return .20 + $this->beverage->cost(); 
} 
} 

class Whip extends CondimentDecorator { 
public $beverage; 

public function __construct(Beverage $beverage) { 
$this->beverage = $beverage; 
} 
public function getDescription() { 
return $this->beverage->getDescription() . ", Whip"; 
} 
public function cost() { 
return .10 + $this->beverage->cost(); 
} 
} 

class Soy extends CondimentDecorator { 
public $beverage; 

public function __construct(Beverage $beverage) { 
$this->beverage = $beverage; 
} 
public function getDescription() { 
return $this->beverage->getDescription() . ", Soy"; 
} 
public function cost() { 
return .15 + $this->beverage->cost(); 
} 
} 

$beverage = new Espresso(); 
echo $beverage->getDescription() . "n"; 
$beverage2 = new DarkRoast(); 
$beverage2 = new Mocha($beverage2); 
$beverage2 = new Mocha($beverage2); 
$beverage2 = new Whip($beverage2); 
echo $beverage2->getDescription() . " $" . $beverage2->cost() . "n"; 

$beverage3 = new HouseBlend(); 
$beverage3 = new Soy($beverage3); 
$beverage3 = new Mocha($beverage3); 
$beverage3 = new Whip($beverage3); 
echo $beverage3->getDescription() . " $" . $beverage3->cost() . "n"; 
?> 

The state pattern
 
<?php 

class GumballMachine { 
const SOLD_OUT = 0; 
const NO_QUARTER = 1; 
const HAS_QUARTER = 2; 
const SOLD = 3; 

public $state = self::SOLD_OUT; 
public $count = 0; 

public function __construct($count) { 
$this->count = $count; 
if ($count > 0) { 
$this->state = self::NO_QUARTER; 
} 
} 

public function insertQuarter() { 
if ($this->state == self::HAS_QUARTER) { 
echo "You can't insert another quarter!n"; 
} else if ($this->state == self::NO_QUARTER) { 
$this->state = self::HAS_QUARTER; 
echo "You inserted a quarter!n"; 
} else if ($this->state == self::SOLD_OUT) { 
echo "You can't insert a quarter, the machine is sold out!n"; 
} else if ($this->state == self::SOLD) { 
echo "Please wait, we're already giving you a gumball!n"; 
} 
} 
} 

$obj = new GumballMachine(0); 
print_r($obj) 

?> 

Related articles: