271月/130
《Head First 设计模式》代码之PHP版
《Head First 设计模式》是本不错的讲解设计模式的书,不像F4写的那么枯燥,应该算是比较容易理解的好书。书中的例子都比较浅显易懂,不过由于是外国佬写的,所以例子的习惯不是很附合中国特色,可能偶尔看起来有些别扭,还有语言习惯也不是中国风。当然看过这本书之后,你才能深刻理解设计模式到底能为你解决哪些题,不能为你解决哪些问题(比如不能代替你的编码)。
策略模式
- <?php
- /**
- * 策略模式
- * 定义了算法族,分别封装起来,让它们之间可以互相替换,
- * 此模式让算法的变化独立于使用算法的客户。
- */
- //飞行行为接口
- interface FlyBehavior {
- public function fly();
- }
- //呱呱叫行为接口
- interface QuackBehavior {
- public function quack();
- }
- //翅膀飞行
- class FlyWithWings implements FlyBehavior {
- public function fly() {
- echo "I'm flying!!/n";
- }
- }
- //不会飞
- 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 "Quack/n";
- }
- }
- class Squeak implements QuackBehavior {
- public function quack() {
- echo "Squeak/n";
- }
- }
- 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();
- //提供新的能力
- $model->setFlyBehavior(new FlyRocketPowered());
- $model->setQuackBehavior(new Squeak());
- $model->performFly();
- $model->performQuack();
- ?>
单件模式
- <?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);
- ?>
工厂方法模式
- <?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 350/n";
- }
- public function cut() {
- echo "Cutting the pizza into diagonal slices/n";
- }
- public function box() {
- echo "Place pizza in official PizzaStore box/n";
- }
- 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 slices/n";
- }
- }
- $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";
- ?>
工厂模式
- <?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 350/n";
- }
- public function cut() {
- echo "Cutting the pizza into diagonal slices/n";
- }
- public function box() {
- echo "Place pizza in official PizzaStore box/n";
- }
- 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');
- ?>
观察者模式
- <?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 "温度:" . $this->temperature . "; 湿度:" . $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 "温度:" . $this->temperature . "; 湿度:" . $this->humidity . "%; 气压:" . $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);
- ?>
命令模式
- <?php
- class Light {
- public function __construct() {
- }
- public function on() {
- echo "Light On/n";
- }
- public function off() {
- echo "Light Off/n";
- }
- }
- 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();
- ?>
装饰者模式
- <?php
- /**
- * 装饰着模式
- * 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
- */
- abstract class Beverage {
- public $description = "Unknown Beverage";
- public function getDescription() {
- return $this->description;
- }
- public abstract function cost();
- }
- abstract class CondimentDecorator extends Beverage {
- //JAVA代码里这里是个抽象类,PHP不允许这么做
- 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";
- ?>
状态模式
- <?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)
- ?>
Leave a comment