├── .gitignore ├── README.md ├── example └── trunk │ ├── class │ ├── example │ │ ├── abstractClassAndInterface.php │ │ ├── couplingAndCohesion.php │ │ └── polymorphism.php │ └── pattern │ │ ├── abstractFactory.php │ │ ├── adapter.php │ │ ├── bridge.php │ │ ├── builder.php │ │ ├── chainOfResponsibility.php │ │ ├── command.php │ │ ├── commandUndo.php │ │ ├── composite.php │ │ ├── decorator.php │ │ ├── facade.php │ │ ├── factory.php │ │ ├── flyweight.php │ │ ├── interpreter.php │ │ ├── iterator.php │ │ ├── mediator.php │ │ ├── memento.php │ │ ├── observer.php │ │ ├── prototype.php │ │ ├── proxy.php │ │ ├── simpleFactory.php │ │ ├── singleton.php │ │ ├── state.php │ │ ├── strategy.php │ │ ├── templateMethod.php │ │ └── visitor.php │ └── public │ ├── example │ ├── abstractClassAndInterface.php │ ├── couplingAndCohesion.php │ └── polymorphism.php │ └── pattern │ ├── .DS_Store │ ├── abstractFactory.php │ ├── adapter.php │ ├── bridge.php │ ├── builder.php │ ├── chainOfResponsibility.php │ ├── command.php │ ├── commandUndo.php │ ├── composite.php │ ├── decorator.php │ ├── facade.php │ ├── factory.php │ ├── flyweight.php │ ├── interpreter.php │ ├── iterator.php │ ├── mediator.php │ ├── memento.php │ ├── observer.php │ ├── prototype.php │ ├── proxy.php │ ├── simpleFactory.php │ ├── singleton.php │ ├── state.php │ ├── strategy.php │ ├── templateMethod.php │ └── visitor.php └── slide.ppt /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows 2 | Thumbs.db 3 | Desktop.ini 4 | 5 | # OSX 6 | .DS_Store 7 | *.DS_Store 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #設計模式 for PHP 2 | 3 | ### 引言 4 | 5 | 目前公司所接觸的專案與開發項目規模越來越大,怎樣設計出可以滿足多變的修改與擴充需求的系統架構,已經變成一個重要的課題。而Design Pattern則是解決上述需求的一個解決方法。它是對軟體設計中普遍存在(反覆出現)的各種問題,所提出的解決方案。它可以運用在大多數物件導向的程式語言中,它能夠避免會引起麻煩的緊耦合,以增強軟體設計面對並適應變化的能力。 6 | 7 | 有鑒於目前市面上現有書籍資料較為艱澀難懂,網路資料較為鬆散雜亂。因此在筆者學習的Design Pattern的過程中,整理出本筆記,希望能夠幫助大家能夠不用花這麼多學習時間,就可以比較容易的理解Design Pattern,並且運用在實際的專案上。 8 | 9 | 由於本筆記的資料皆採自與市面出版書籍與網路資料,由於筆者本身能力有限,筆記裡面也許有說明不清楚或是不正確的地方,歡迎大家提出問題與為本筆記勘誤。信箱: 10 | 11 | 12 | ### 目前有收錄的設計模式有: 13 | 14 | #### Creational Patterns(生成模式) 15 | 16 | * Simple Factory(簡單工廠模式) 17 | * Factory Method(工廠方法模式) 18 | * Abstract Factory(抽象工廠模式) 19 | * Builder(生成器模式) 20 | * Prototype(原型模式) 21 | * Singleton(單例模式) 22 | 23 | #### Structural Patterns(結構模式) 24 | 25 | * Adapter(轉接器模式) 26 | * Bridge(橋梁模式) 27 | * Composite(合成模式) 28 | * Decorator(裝飾模式) 29 | * Façade(表象模式) 30 | * Flyweight(享元模式) 31 | * Proxy(代理人模式) 32 | 33 | #### Behavioral Patterns(行為模式): 34 | 35 | * Chain of Responsibility(責任鍊模式) 36 | * Command(命令模式) 37 | * Interpreter(解釋器模式) 38 | * Iterator(迭代器模式) 39 | * Mediator(中介者模式) 40 | * Memento(備忘錄模式) 41 | * Observer(觀察者模式) 42 | * State(狀態模式) 43 | * Strategy(策略模式) 44 | * Template Method(樣板方法模式) 45 | * Visitor(訪客模式) -------------------------------------------------------------------------------- /example/trunk/class/example/abstractClassAndInterface.php: -------------------------------------------------------------------------------- 1 | age = $age; 11 | } 12 | 13 | public function getAge(){ 14 | return $this->age; 15 | } 16 | } 17 | 18 | interface Insurable 19 | { 20 | public function getValue(); 21 | } 22 | 23 | // 繼承至Animal 24 | class Shark extends Animal 25 | { 26 | private $speed; // 游泳速度 27 | 28 | public function __construct($speed,$age) { 29 | parent::__construct($age); 30 | $this->speed = $speed; 31 | } 32 | 33 | public function getSpeed() { 34 | return $this->speed; 35 | } 36 | 37 | // 實作自abstract class繼承來的method 38 | public function getOwned() { 39 | return ("getOwned Shark String"); 40 | } 41 | } 42 | 43 | // 繼承至Animal、定義了Insurable介面 44 | class Pet extends Animal implements Insurable 45 | { 46 | private $name; 47 | 48 | public function __construct($name,$age) { 49 | parent::__construct($age); 50 | $this->name = $name; 51 | } 52 | 53 | public function getName() { 54 | return $this->name; 55 | } 56 | 57 | // 實作自abstract class繼承來的method 58 | public function getOwned() { 59 | return ("getOwned Pet String"); 60 | } 61 | 62 | // 實作自Interface定義的method 63 | public function getValue() { 64 | return ("getValue Pet String"); 65 | } 66 | } 67 | 68 | // 繼承至Pet,同時也繼承了Pet實作getValue()的部分, 69 | // 等於也繼承了Insurable Interface 70 | class Human extends Pet 71 | { 72 | private $money; 73 | 74 | public function __construct($money,$name,$age) { 75 | parent::__construct($name, $age); 76 | $this->money = $money; 77 | } 78 | 79 | public function getMoney() { 80 | return $this->money; 81 | } 82 | 83 | // 實作自abstract class繼承來的method 84 | public function getOwned() { 85 | return ("getOwned Human String"); 86 | } 87 | } 88 | 89 | // 定義了Insurable介面 90 | class House implements Insurable 91 | { 92 | // 實作自Interface定義的method 93 | public function getValue() { 94 | return ("getValue House String"); 95 | } 96 | 97 | } 98 | 99 | 100 | abstract class Reader 101 | { 102 | private $items = array(); 103 | 104 | public function getItems() { 105 | return $this->items; 106 | } 107 | 108 | public function setItem($item) { 109 | array_push($this->items, $item); 110 | } 111 | 112 | public abstract function printItems(); 113 | } 114 | 115 | 116 | 117 | class InsurableReader extends Reader 118 | { 119 | public function addItem(Insurable $item) { 120 | parent::setItem($item); 121 | } 122 | 123 | public function printItems() { 124 | foreach (parent::getItems() as $item) { 125 | echo 'getValue():' . $item->getValue() . '
'; 126 | } 127 | } 128 | } 129 | 130 | class AnimalReader extends Reader 131 | { 132 | public function addItem(Animal $item) { 133 | parent::setItem($item); 134 | } 135 | 136 | public function printItems() { 137 | foreach(parent::getItems() as $item) { 138 | echo 'getOwned():' . $item->getOwned() . '
'; 139 | } 140 | } 141 | } 142 | ?> -------------------------------------------------------------------------------- /example/trunk/class/example/couplingAndCohesion.php: -------------------------------------------------------------------------------- 1 | radius = $radius; 9 | } 10 | } 11 | 12 | class Square 13 | { 14 | public $side; 15 | 16 | public function __construct($side) { 17 | $this->side = $side; 18 | } 19 | } 20 | 21 | 22 | 23 | class Lister 24 | { 25 | public $items = array(); 26 | 27 | public function addItem($item) { 28 | array_push($this->items, $item); 29 | } 30 | 31 | public function out() { 32 | 33 | echo "+———-+———–+———+
34 | | Type | parameter | value |
35 | +———-+———–+———+
"; 36 | 37 | for ($i = 0, $s = sizeof($this->items); $i < $s; $i++) { 38 | 39 | // 判斷是Circle還是Square 40 | if ($this->items[$i] instanceof Circle) { 41 | echo "| Circle | radius | " . sprintf('%5.2f', $this->items[$i]->radius) . " |
"; 42 | } else { 43 | echo "| Square | side | " . sprintf('%5.2f', $this->items[$i]->side) . " |
"; 44 | } 45 | echo "+———-+———–+———+
"; 46 | } 47 | } 48 | } 49 | 50 | 51 | // 如果增加其他形狀... 52 | 53 | /* 54 | class Circle 55 | { 56 | public $radius; 57 | 58 | public function __construct($radius) { 59 | $this->radius = $radius; 60 | } 61 | } 62 | 63 | class Square 64 | { 65 | public $side; 66 | 67 | public function __construct($side) { 68 | $this->side = $side; 69 | } 70 | } 71 | 72 | class Star 73 | { 74 | public $angle; 75 | 76 | public function __construct($angle) { 77 | $this->angle = $angle; 78 | } 79 | } 80 | 81 | class Diamond 82 | { 83 | public $diam; 84 | 85 | public function __construct($diam) { 86 | $this->diam = $diam; 87 | } 88 | } 89 | 90 | 91 | class Lister 92 | { 93 | public $items = array(); 94 | 95 | public function addItem($item) { 96 | array_push($this->items, $item); 97 | } 98 | 99 | public function out() { 100 | 101 | echo "+———-+———–+———+
102 | | Type | parameter | value |
103 | +———-+———–+———+
"; 104 | 105 | for ($i = 0, $s = sizeof($this->items); $i < $s; $i++) { 106 | 107 | //判斷是Circle還是Square 108 | if ($this->items[$i] instanceof Circle){ 109 | echo "| Circle | radius | " . sprintf('%5.2f', $this->items[$i]->radius) . " |
"; 110 | } else if ($this->items[$i] instanceof Square){ 111 | echo "| Square | side | " . sprintf('%5.2f', $this->items[$i]->side) . " |
"; 112 | } else if ($this->items[$i] instanceof Star){ 113 | echo "| Star | angle | " . sprintf('%5.2f', $this->items[$i]->side) . " |
"; 114 | } else { 115 | echo "| Diamond | diam | " . sprintf('%5.2f', $this->items[$i]->side) . " |
"; 116 | } 117 | 118 | echo "+———-+———–+———+
"; 119 | } 120 | } 121 | } 122 | */ 123 | 124 | 125 | 126 | //程式碼重構 127 | 128 | abstract class Shape 129 | { 130 | private $value; 131 | 132 | public function __construct($value) { 133 | $this->value = $value; 134 | } 135 | 136 | public function getValue() { 137 | return $this->value; 138 | } 139 | 140 | public abstract function out(); 141 | } 142 | 143 | class Circle extends Shape 144 | { 145 | public function out(){ 146 | echo "| Circle | radius | " . sprintf('%5.2f', $this->getValue()) . " |
"; 147 | } 148 | } 149 | 150 | class Square extends Shape 151 | { 152 | public function out() { 153 | echo "| Square | side | " . sprintf('%5.2f', $this->getValue()) . " |
"; 154 | } 155 | } 156 | 157 | 158 | class Lister 159 | { 160 | public $items = array(); 161 | 162 | public function addItem(Shape $item) { 163 | array_push($this->items, $item); 164 | } 165 | 166 | public function out() { 167 | 168 | echo "+———-+———–+———+
169 | | Type | parameter | value |
170 | +———-+———–+———+
"; 171 | 172 | for ($i = 0, $s = sizeof($this->items); $i < $s; $i++) { 173 | $this->items[$i]->out(); 174 | echo "+———-+———–+———+
"; 175 | } 176 | } 177 | } 178 | ?> -------------------------------------------------------------------------------- /example/trunk/class/example/polymorphism.php: -------------------------------------------------------------------------------- 1 | draw(); 9 | } 10 | } 11 | 12 | class Circle 13 | { 14 | function draw(){ 15 | echo "畫圓圈
"; 16 | } 17 | } 18 | 19 | class Rectangle 20 | { 21 | function draw(){ 22 | echo "畫長方形
"; 23 | } 24 | } 25 | */ 26 | 27 | // 第二種:也是一樣沒用到繼承,只不過採用呼叫 shape 的靜態方法,使物件在初始化時就開始動作。 28 | /* 29 | class Shape 30 | { 31 | static function draw($temp){ 32 | $temp->draw(); 33 | } 34 | } 35 | 36 | class Circle 37 | { 38 | function __construct() { 39 | shape::draw($this); 40 | } 41 | 42 | function draw(){ 43 | echo "畫圓圈
"; 44 | } 45 | } 46 | 47 | class Rectangle 48 | { 49 | function __construct() { 50 | shape::draw($this); 51 | } 52 | 53 | function draw(){ 54 | echo "畫長方形
"; 55 | } 56 | } 57 | */ 58 | 59 | abstract class Shape 60 | { 61 | private $draw; 62 | 63 | function setDraw($draw) { 64 | $this->draw = $draw; 65 | } 66 | 67 | function getDraw() { 68 | return $this->draw; 69 | } 70 | } 71 | 72 | class Circle extends Shape 73 | { 74 | function __construct() { 75 | $this->setDraw('畫圈圈'); 76 | } 77 | } 78 | 79 | class Rectangle extends Shape 80 | { 81 | function __construct() { 82 | $this->setDraw('畫長方形'); 83 | } 84 | } 85 | 86 | class Drawer 87 | { 88 | private $shapes = array(); 89 | 90 | function addShape(Shape $shape) { 91 | array_push($this->shapes, $shape); 92 | } 93 | 94 | function drawAllShapes() { 95 | foreach($this->shapes as $shape) { 96 | echo $shape->getDraw() . '
'; 97 | } 98 | } 99 | } 100 | 101 | 102 | ?> 103 | -------------------------------------------------------------------------------- /example/trunk/class/pattern/abstractFactory.php: -------------------------------------------------------------------------------- 1 |
"; 61 | } 62 | } 63 | 64 | // 士兵 65 | class TerranSolider extends TerranUnit 66 | { 67 | public function playSlogan() { 68 | echo "快給我戰鬥藥吧!!

"; 69 | } 70 | } 71 | 72 | // 飛機 73 | class TerranAircraft extends TerranUnit 74 | { 75 | public function playSlogan() { 76 | echo "我已經準備好起飛出擊了,長官!

"; 77 | } 78 | } 79 | 80 | 81 | 82 | 83 | 84 | // 抽象蟲族單位 85 | abstract class ZergUnit 86 | { 87 | public abstract function shout(); // 嘶吼 88 | } 89 | 90 | // 工人 91 | class ZergWorker extends ZergUnit 92 | { 93 | public function shout() { 94 | echo "(黏液黏液),請問主宰您想長出什麼建築物?

"; 95 | } 96 | } 97 | 98 | // 士兵 99 | class ZergSolider extends ZergUnit 100 | { 101 | public function shout() { 102 | echo "給我更多的人類!!!

"; 103 | } 104 | } 105 | 106 | // 飛螳 107 | class ZergAircraft extends ZergUnit 108 | { 109 | public function shout() { 110 | echo "嘎~~~~嘎~~~~~嘎~~~~

"; 111 | } 112 | } 113 | 114 | 115 | 116 | 117 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/adapter.php: -------------------------------------------------------------------------------- 1 | "; 20 | } 21 | 22 | public function usb_move() { 23 | echo "USB滑鼠移動
"; 24 | } 25 | 26 | public function usb_connect() { 27 | echo "USB滑鼠連接
"; 28 | } 29 | } 30 | 31 | // PS/2滑鼠介面 32 | interface Ps2Mouse 33 | { 34 | public function ps2_click(); 35 | public function ps2_move(); 36 | public function ps2_connect(); 37 | } 38 | 39 | // 簡單PS/2滑鼠 40 | class SimplePs2Mouse implements Ps2Mouse 41 | { 42 | public function ps2_click() { 43 | echo "PS/2滑鼠點一下
"; 44 | } 45 | 46 | public function ps2_move() { 47 | echo "PS/2滑鼠移動
"; 48 | } 49 | 50 | public function ps2_connect() { 51 | echo "PS/2滑鼠連接
"; 52 | } 53 | } 54 | 55 | // PS/2 -> USB轉接器 56 | class Ps2UsbAdapter implements UsbMouse 57 | { 58 | private $ps2Mouse; 59 | 60 | public function __construct(Ps2Mouse $ps2Mouse) { 61 | $this->ps2Mouse = $ps2Mouse; 62 | } 63 | 64 | public function usb_click() { 65 | $this->ps2Mouse->ps2_click(); 66 | } 67 | 68 | public function usb_move() { 69 | $this->ps2Mouse->ps2_move(); 70 | } 71 | 72 | public function usb_connect() { 73 | $this->ps2Mouse->ps2_connect(); 74 | } 75 | } 76 | 77 | 78 | 79 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/bridge.php: -------------------------------------------------------------------------------- 1 | "; 15 | } 16 | 17 | } 18 | 19 | class AndroidAngryBirdSpace implements AngryBird 20 | { 21 | public function play() { 22 | echo "您開始玩Android平台的AngryBird宇宙版本
"; 23 | } 24 | } 25 | 26 | class AndroidAngryBirdRio implements AngryBird 27 | { 28 | public function play() { 29 | echo "您開始玩Android平台的AngryBirdRio版本
"; 30 | } 31 | } 32 | 33 | 34 | 35 | class IOSAngryBirdNormal implements AngryBird 36 | { 37 | public function play() { 38 | echo "您開始玩iOS平台的AngryBird普通版本
"; 39 | } 40 | } 41 | 42 | class IOSAngryBirdSpace implements AngryBird 43 | { 44 | public function play() { 45 | echo "您開始玩iOS平台的AngryBird宇宙版本
"; 46 | } 47 | } 48 | 49 | 50 | class IOSAngryBirdRio implements AngryBird 51 | { 52 | public function play() { 53 | echo "您開始玩iOS平台的AngryBirdRio版本
"; 54 | } 55 | } 56 | */ 57 | 58 | // implementor 59 | interface Platform 60 | { 61 | public function control(); 62 | } 63 | 64 | // concrete implementor 65 | class AndroidPlatform implements Platform 66 | { 67 | public function control() { 68 | return "Android"; 69 | } 70 | } 71 | 72 | // concrete implementor 73 | class IOSPlatform implements Platform 74 | { 75 | public function control() { 76 | return "IOS"; 77 | } 78 | } 79 | 80 | 81 | // abstraction 82 | abstract class AngryBird 83 | { 84 | protected $platform = null; 85 | 86 | public function __construct(Platform $platform) { 87 | $this->platform = $platform; 88 | } 89 | 90 | public abstract function play(); 91 | } 92 | 93 | 94 | 95 | // refined abstraction 96 | class AngryBirdNormal extends AngryBird 97 | { 98 | 99 | public function play() { 100 | echo "您開始玩AngryBird普通版本, 平台為:" . $this->platform->control() . "
"; 101 | } 102 | } 103 | 104 | // refined abstraction 105 | class AngryBirdSpace extends AngryBird 106 | { 107 | public function play() { 108 | echo "您開始玩AngryBird宇宙版本, 平台為:" . $this->platform->control() . "
"; 109 | } 110 | } 111 | 112 | // refined abstraction 113 | class AngryBirdRio extends AngryBird 114 | { 115 | public function play() { 116 | echo "您開始玩AngryBirdRio版本, 平台為:" . $this->platform->control() . "
"; 117 | } 118 | } 119 | 120 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/builder.php: -------------------------------------------------------------------------------- 1 | food = $food; 12 | } 13 | 14 | public function setDrink($drink) { 15 | $this->drink = $drink; 16 | } 17 | 18 | public function setDessert($dessert) { 19 | $this->dessert = $dessert; 20 | } 21 | 22 | public function showMeal() { 23 | echo $this->food . ", " . $this->drink . ", " . $this->dessert . "
"; 24 | } 25 | } 26 | 27 | // Builder 28 | abstract class MealBuilder 29 | { 30 | protected $meal = null; 31 | 32 | public function __construct() { 33 | $this->meal = new Meal(); 34 | } 35 | 36 | public abstract function buildFood(); 37 | public abstract function buildDrink(); 38 | public abstract function buildDessert(); 39 | public function getMeal() { 40 | return $this->meal; 41 | } 42 | } 43 | 44 | // ConcreteBuilder 45 | class ChickenKitMealBuilder extends MealBuilder 46 | { 47 | 48 | public function buildFood() { 49 | $this->meal->setFood("一個雞腿堡"); 50 | } 51 | 52 | public function buildDrink() { 53 | $this->meal->setDrink("一杯可樂"); 54 | } 55 | 56 | public function buildDessert() { 57 | $this->meal->setDessert("一包薯條"); 58 | } 59 | } 60 | 61 | // ConcreteBuilder 62 | class BeefKitMealBuilder extends MealBuilder 63 | { 64 | public function buildFood() { 65 | $this->meal->setFood("一個牛肉堡"); 66 | } 67 | 68 | public function buildDrink() { 69 | $this->meal->setDrink("一杯紅茶"); 70 | } 71 | 72 | public function buildDessert() { 73 | $this->meal->setDessert("一個蘋果派"); 74 | } 75 | } 76 | 77 | // Director 78 | class MealDirector 79 | { 80 | private $mealBuilder; 81 | 82 | public function setMealBuilder(MealBuilder $mealBuilder) { 83 | $this->mealBuilder = $mealBuilder; 84 | } 85 | 86 | public function buildMeal() { 87 | $this->mealBuilder->buildFood(); 88 | $this->mealBuilder->buildDrink(); 89 | $this->mealBuilder->buildDessert(); 90 | 91 | return $this->mealBuilder->getMeal(); 92 | 93 | } 94 | } 95 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/chainOfResponsibility.php: -------------------------------------------------------------------------------- 1 | handler = $handler; 11 | } 12 | 13 | protected function handleRequest($request) { 14 | if ($this->handler != null) { 15 | return $this->handler->handleRequest($request); // 如果要傳遞的下家存在,就將request往下傳,如果下家不存在則拋出處理完的request 16 | } else { 17 | return "無法處理此類型的資料!"; 18 | } 19 | } 20 | } 21 | 22 | // ConcreteHandler 資料庫logger 23 | class dbLogger extends Logger 24 | { 25 | public function handleRequest($request) { 26 | 27 | if (strpos($request, "db") !== false) { 28 | return "將db log寫入"; 29 | } else { 30 | return parent::handleRequest($request); 31 | } 32 | } 33 | } 34 | 35 | // ConcreteHandler Session Logger 36 | class sessionLogger extends Logger 37 | { 38 | public function handleRequest($request) { 39 | 40 | if (strpos($request, "session") !== false) { 41 | return "將session log寫入"; 42 | } else { 43 | return parent::handleRequest($request); 44 | } 45 | } 46 | } 47 | 48 | // ConcreteHandler Cache Logger 49 | class cacheLogger extends Logger 50 | { 51 | public function handleRequest($request) { 52 | 53 | if (strpos($request, "cache") !== false) { 54 | return "cache log寫入"; 55 | } else { 56 | return parent::handleRequest($request); 57 | } 58 | } 59 | } 60 | 61 | 62 | // 不純責任鍊範例 63 | 64 | // Handler 65 | abstract class DirtyWordFilter 66 | { 67 | protected $keyWord = array(); 68 | protected $handler = null; 69 | public function setSuccessor(DirtyWordFilter $handler) { // 設定責任要傳遞的下家 70 | $this->handler = $handler; 71 | } 72 | protected function handleRequest($request) { 73 | if($this->handler != null) { // 如果要傳遞的下家存在,就將request往下傳,如果下家不存在則拋出處理完的request 74 | return $this->handler->handleRequest($request); 75 | } else { 76 | return $request; 77 | } 78 | } 79 | } 80 | 81 | // ConcreteHandler 82 | class ChineseDirtyWordFilter extends DirtyWordFilter 83 | { 84 | public function __construct() { 85 | $this->keyWord = array( 86 | "豬頭", "笨蛋", "白癡", "三八", "王八蛋" 87 | ); 88 | } 89 | 90 | public function handleRequest($request) { 91 | 92 | foreach($this->keyWord as $row) { 93 | $request = str_replace($row, "***", $request); 94 | } 95 | return parent::handleRequest($request); 96 | } 97 | } 98 | 99 | // ConcreteHandler 100 | class EnglishDirtyWordFilter extends DirtyWordFilter 101 | { 102 | public function __construct() { 103 | $this->keyWord = array( 104 | "son of bitch", "idiot", "asshole", "bullshit" 105 | ); 106 | } 107 | 108 | public function handleRequest($request) { 109 | 110 | foreach($this->keyWord as $row) { 111 | $request = str_replace($row, "???", $request); 112 | } 113 | return parent::handleRequest($request); 114 | } 115 | } 116 | 117 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/command.php: -------------------------------------------------------------------------------- 1 | "; 47 | 48 | } 49 | 50 | public function powerOff() { 51 | 52 | echo "汽車引擎關閉
"; 53 | } 54 | 55 | public function move() { 56 | 57 | echo "汽車前進
"; 58 | } 59 | 60 | public function stop() { 61 | 62 | echo "汽車停止
"; 63 | 64 | } 65 | 66 | public function turnLeft() { 67 | echo "汽車左轉
"; 68 | } 69 | 70 | public function turnRight() { 71 | echo "汽車右轉
"; 72 | } 73 | } 74 | 75 | class Boat extends Vehicle 76 | { 77 | public function powerOn() { 78 | echo "汽船引擎發動
"; 79 | } 80 | 81 | public function powerOff() { 82 | echo "汽船引擎停止
"; 83 | } 84 | 85 | public function move() { 86 | echo "汽船前進
"; 87 | } 88 | 89 | public function stop() { 90 | echo "汽船停止
"; 91 | } 92 | } 93 | 94 | 95 | 96 | // Command 這邊用abstract class也可以 97 | interface Command 98 | { 99 | public function execute(); 100 | } 101 | 102 | // ConcreteCommand 103 | class PowerOnCommand implements Command 104 | { 105 | private $vehicle; 106 | 107 | public function __construct(Vehicle $vehicle) { 108 | $this->vehicle = $vehicle; 109 | } 110 | 111 | public function execute() { 112 | 113 | $this->vehicle->powerOn(); 114 | 115 | } 116 | } 117 | 118 | class PowerOffCommand implements Command 119 | { 120 | private $vehicle; 121 | 122 | public function __construct(Vehicle $vehicle) { 123 | $this->vehicle = $vehicle; 124 | } 125 | 126 | public function execute() { 127 | $this->vehicle->powerOff(); 128 | 129 | } 130 | } 131 | 132 | class TurnLeftCommand implements Command 133 | { 134 | private $vehicle; 135 | 136 | public function __construct(Vehicle $vehicle) { 137 | $this->vehicle = $vehicle; 138 | } 139 | 140 | public function execute() { 141 | $this->vehicle->turnLeft(); 142 | } 143 | } 144 | 145 | class TurnRightCommand implements Command 146 | { 147 | private $vehicle; 148 | 149 | public function __construct(Vehicle $vehicle) { 150 | $this->vehicle = $vehicle; 151 | } 152 | 153 | public function execute() { 154 | $this->vehicle->turnRight(); 155 | 156 | } 157 | } 158 | 159 | // 空指令 160 | class NoCommand implements Command 161 | { 162 | public function execute(){} 163 | } 164 | 165 | // 如果想加一個蛇行的功能時...實作巨集命令 166 | class MarcoCommand implements Command 167 | { 168 | private $commands = array(); 169 | 170 | public function __construct($commands) { 171 | $this->commands = $commands; 172 | } 173 | 174 | public function execute() { 175 | foreach($this->commands as $command) { 176 | $command->execute(); 177 | } 178 | } 179 | } 180 | 181 | 182 | 183 | // Invoker 184 | class RemoteControl 185 | { 186 | private $commands = array(8); 187 | 188 | // 建立八個沒任何命令的空按鈕 189 | function __construct() { 190 | for($i=0; $i<8; $i++) { 191 | $this->commands[$i] = new NoCommand(); 192 | } 193 | } 194 | 195 | // 設定按鈕命令 196 | function setCommand($slot, Command $cmd) { 197 | //array_push($this->commands, $cmd); 198 | $this->commands[$slot] = $cmd; 199 | } 200 | 201 | // 按下按鈕 202 | function execute($slot) { 203 | /* 204 | foreach($this->commands as $key => $value){ 205 | $this->commands[$key]->execute(); 206 | }*/ 207 | $this->commands[$slot]->execute(); 208 | } 209 | } 210 | 211 | 212 | 213 | 214 | ?> 215 | -------------------------------------------------------------------------------- /example/trunk/class/pattern/commandUndo.php: -------------------------------------------------------------------------------- 1 | text = $text; 49 | } 50 | 51 | public function cut($cutText){ 52 | $this->text = str_replace($cutText, "", $this->text); 53 | $this->showText(); 54 | } 55 | 56 | public function paste($pasteText) { 57 | $this->text .= $pasteText; 58 | $this->showText(); 59 | } 60 | 61 | public function getText() { 62 | return $this->text; 63 | } 64 | 65 | public function setText($text) { 66 | $this->text = $text; 67 | $this->showText(); 68 | } 69 | 70 | protected function showText() { 71 | echo $this->text.'
'; 72 | } 73 | } 74 | 75 | 76 | 77 | 78 | // Command 這邊用abstract class也可以 79 | interface Command 80 | { 81 | public function execute($text); 82 | public function undo(); 83 | public function redo(); 84 | } 85 | 86 | // ConcreteCommand 87 | class CutCommand implements Command 88 | { 89 | private $textEditor; 90 | private $text = array(); // 原始數據備份陣列 91 | private $textRedo = array(); // 輸入數據備份陣列 92 | 93 | public function __construct(TextEditor $textEditor) { 94 | $this->textEditor = $textEditor; 95 | } 96 | 97 | public function execute($text) { 98 | 99 | // 備份舊資料 100 | array_push($this->text, $this->textEditor->getText()); 101 | 102 | // 裁切資料 103 | $this->textEditor->cut($text); 104 | } 105 | 106 | public function undo() { 107 | if (count($this->text) <= 0) { 108 | return false; 109 | } 110 | $text = array_pop($this->text); 111 | array_push($this->textRedo, $this->textEditor->getText()); 112 | $this->textEditor->setText($text); 113 | } 114 | 115 | public function redo() { 116 | if (count($this->textRedo) <= 0) { 117 | return false; 118 | } 119 | $textRedo = array_pop($this->textRedo); 120 | array_push($this->text, $this->textEditor->getText()); 121 | $this->textEditor->setText($textRedo); 122 | } 123 | } 124 | 125 | class PasteCommand implements Command 126 | { 127 | private $textEditor; 128 | private $text = array(); // 原始數據備份陣列 129 | private $textRedo = array(); // 輸入數據備份陣列 130 | 131 | public function __construct(TextEditor $textEditor) { 132 | $this->textEditor = $textEditor; 133 | } 134 | 135 | public function execute($text) { 136 | 137 | // 備份舊資料 138 | array_push($this->text, $this->textEditor->getText()); 139 | 140 | // 貼上資料 141 | $this->textEditor->paste($text); 142 | } 143 | 144 | public function undo(){ 145 | if (count($this->text) <= 0) { 146 | return; 147 | } 148 | $text = array_pop($this->text); 149 | array_push($this->textRedo, $this->textEditor->getText()); 150 | $this->textEditor->setText($text); 151 | } 152 | 153 | public function redo(){ 154 | if (count($this->textRedo) <= 0) { 155 | return; 156 | } 157 | $textRedo = array_pop($this->textRedo); 158 | array_push($this->text, $this->textEditor->getText()); 159 | $this->textEditor->setText($textRedo); 160 | } 161 | } 162 | 163 | 164 | 165 | 166 | // Invoker 167 | class ControlManager 168 | { 169 | private $undoList = array(); 170 | private $redoList = array(); 171 | 172 | public function __construct() { 173 | 174 | } 175 | 176 | private function storeCommand(Command $cmd) { 177 | array_push($this->undoList, $cmd); 178 | } 179 | 180 | public function clearAllCommand() { 181 | $this->undoList = array(); 182 | $this->redoList = array(); 183 | } 184 | 185 | public function undo(){ 186 | 187 | if (count($this->undoList) <= 0) { 188 | return; 189 | } 190 | 191 | $cmd = array_pop($this->undoList); 192 | $cmd->undo(); 193 | array_push($this->redoList, $cmd); 194 | } 195 | 196 | public function redo(){ 197 | 198 | if (count($this->redoList) <= 0) { 199 | return; 200 | } 201 | $cmd = array_pop($this->redoList); 202 | $cmd->redo(); 203 | array_push($this->undoList, $cmd); 204 | } 205 | 206 | public function execute(Command $cmd, $text) { 207 | $this->storeCommand($cmd); 208 | $cmd->execute($text); 209 | } 210 | } 211 | 212 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/composite.php: -------------------------------------------------------------------------------- 1 | units, $unit); 36 | } 37 | 38 | public function bombardStrength() { // 輸出整個軍隊的攻擊力 39 | $ret = 0; 40 | foreach ($this->units as $unit) { 41 | $ret += $unit->bombardStrength(); 42 | } 43 | return $ret; 44 | } 45 | } 46 | */ 47 | 48 | /* 這時候有新的需求,軍隊應該要能夠與其他軍隊合併,並且以後還可以從整併後的軍隊中解散出來 */ 49 | /* 50 | class Army 51 | { 52 | private $units = array(); 53 | 54 | public function addArmy( Army $army) { // 將一軍隊整編進來 55 | array_push($this->armies, $army); 56 | } 57 | 58 | public function addUnit(Unit $unit){ // 將一戰鬥單位加入到軍隊群組中 59 | array_push($this->units, $unit); 60 | } 61 | 62 | public function bombardStrength() { // 輸出整個軍隊+整編進來軍隊的攻擊力 63 | $ret = 0; 64 | foreach ($this->units as $unit) { 65 | $ret += $unit->bombardStrength(); 66 | } 67 | 68 | foreach ($this->armies as $army) { 69 | $ret += $army->bombardStrength(); 70 | } 71 | return $ret; 72 | } 73 | } 74 | */ 75 | 76 | 77 | /* 如果還有其他func, 例如計算整體防禦力、計算整體移動距離等,我們就要對他們一一做修改, 78 | * 如果現在客戶除了軍隊外,還有運兵船這樣的組合戰鬥單元的話.... 79 | */ 80 | 81 | 82 | 83 | 84 | 85 | abstract class Unit 86 | { 87 | public function getComposite() { 88 | return null; 89 | } 90 | 91 | abstract function bombardStrength(); // 輸出戰鬥單位的攻擊力 92 | } 93 | 94 | abstract class CompositeUnit extends Unit 95 | { 96 | private $units = array(); 97 | 98 | public function getComposite() { 99 | return $this; 100 | } 101 | 102 | protected function units() { 103 | return $this->units; 104 | } 105 | 106 | public function addUnit(Unit $unit) { // 將一戰鬥單位加入到軍隊群組中 107 | if (in_Array($unit, $this->units, true)) { 108 | return; 109 | } 110 | $this->units[] = $unit; 111 | } 112 | 113 | public function removeUnit(Unit $unit) { // 將一戰鬥單位從軍隊群組中移除 114 | //$this->units = array_udiff($this->units, array($unit), function($a, $b){ return ($a === $b)?0:1; }); // PHP 5.3寫法 115 | $this->units = array_udiff($this->units, array($unit), create_function('$a, $b', 'return ($a === $b)?0:1;')); 116 | } 117 | } 118 | 119 | 120 | 121 | // 軍隊 122 | class Army extends CompositeUnit 123 | { 124 | public function bombardStrength() { // 計算總攻擊力 125 | $ret = 0; 126 | foreach ($this->units() as $unit) { 127 | $ret += $unit->bombardStrength(); 128 | } 129 | return $ret; 130 | } 131 | } 132 | 133 | // 裝甲運兵車 134 | class TroopCarrier extends CompositeUnit 135 | { 136 | public function addUnit(Unit $unit) { // 將單位加入 137 | if ($unit instanceof Cavalry) { 138 | throw new Exception("Can't get a horse on the vehicle"); 139 | } 140 | parent::addUnit($unit); 141 | } 142 | 143 | public function bombardStrength() { 144 | return 15; 145 | } 146 | } 147 | 148 | 149 | // 弓箭手 150 | class Archer extends Unit 151 | { 152 | public function bombardStrength() { 153 | return 4; 154 | } 155 | } 156 | 157 | // 雷射加農砲 158 | class LaserCannonUnit extends Unit 159 | { 160 | public function bombardStrength() { 161 | return 44; 162 | } 163 | } 164 | 165 | // 騎兵 166 | class Cavalry extends Unit 167 | { 168 | public function bombardStrength() { 169 | return 15; 170 | } 171 | } 172 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/decorator.php: -------------------------------------------------------------------------------- 1 | wealthfactor; 56 | } 57 | } 58 | 59 | abstract class TileDecorator extends Tile 60 | { 61 | protected $tile; 62 | 63 | public function __construct(Tile $tile){ 64 | $this->tile = $tile; 65 | } 66 | } 67 | 68 | // 鑽石裝飾 69 | class DiamondDecorator extends TileDecorator 70 | { 71 | 72 | public function getWealthFactor() { 73 | return $this->tile->getWealthFactor() + 2; 74 | } 75 | } 76 | 77 | // 汙染裝飾 78 | class PollutionDecorator extends TileDecorator 79 | { 80 | 81 | public function getWealthFactor() { 82 | return $this->tile->getWealthFactor() - 4; 83 | } 84 | } 85 | 86 | 87 | /* 88 | class RequestHelper{} 89 | 90 | abstract class ProcessRequest 91 | { 92 | abstract function process(RequestHelper $req); 93 | } 94 | 95 | // 具體組件,decorate會包住這個物件,並且賦予decorate的屬性或動作 96 | class MainProcess extends ProcessRequest 97 | { 98 | function process(RequestHelper $req) { 99 | print __CLASS__.": doing somethig usefule with request
"; 100 | } 101 | } 102 | 103 | // 抽象裝飾 104 | abstract class DecorateProcess extends ProcessRequest 105 | { 106 | protected $processrequest; 107 | function __construct(ProcessRequest $pr) { 108 | $this->processrequest = $pr; 109 | } 110 | } 111 | 112 | 113 | class LogRequest extends DecorateProcess 114 | { 115 | function process(RequestHelper $req) { 116 | print __CLASS__.": logging request
"; 117 | $this->processrequest->process($req); 118 | } 119 | } 120 | 121 | class AuthenticateRequest extends DecorateProcess 122 | { 123 | function process(RequestHelper $req) { 124 | print __CLASS__ . ": authenticating request
"; 125 | $this->processrequest->process($req); 126 | } 127 | } 128 | 129 | class StructureRequest extends DecorateProcess 130 | { 131 | function process(RequestHelper $req){ 132 | print __CLASS__ . ": structuring request data
"; 133 | $this->processrequest->process($req); 134 | } 135 | } 136 | */ 137 | 138 | 139 | ?> 140 | -------------------------------------------------------------------------------- /example/trunk/class/pattern/facade.php: -------------------------------------------------------------------------------- 1 | _adder = new Adder(); 49 | $this->_subtractor = new Subtractor(); 50 | $this->_multiplier = new Multiplier(); 51 | $this->_divider = new Divider(); 52 | } 53 | 54 | public function calculate($expression) { 55 | list($a, $operator, $b) = explode(" ", $expression); 56 | 57 | // eliminating switch constructs is not in the intent of this pattern 58 | switch ($operator) { 59 | case '+': 60 | return $this->_adder->add($a, $b); 61 | break; 62 | case '-': 63 | return $this->_subtractor->subtract($a, $b); 64 | break; 65 | case '*': 66 | return $this->_multiplier->multiply($a, $b); 67 | break; 68 | case '/': 69 | return $this->_divider->divide($a, $b); 70 | break; 71 | } 72 | } 73 | } 74 | */ 75 | 76 | // 收音機與聲音控制器 77 | class Tuner 78 | { 79 | private $amplifier; 80 | private $description; 81 | private $frequency; 82 | 83 | public function __construct(Amplifier $amplifier, $description) { 84 | $this->description = $description; 85 | } 86 | 87 | public function on() { 88 | echo($this->description . " on"); 89 | echo("
"); 90 | } 91 | 92 | public function off() { 93 | echo($this->description . " off"); 94 | echo("
"); 95 | } 96 | 97 | public function setFrequency($frequency) { 98 | echo($this->description . " setting frequency to " . $frequency); 99 | echo("
"); 100 | $this->frequency = $frequency; 101 | } 102 | 103 | public function setAm() { 104 | echo($this->description . " setting AM mode"); 105 | echo("
"); 106 | } 107 | 108 | public function setFm() { 109 | echo($this->description . " setting FM mode"); 110 | echo("
"); 111 | } 112 | } 113 | 114 | // 戲院燈光組 115 | class TheaterLights 116 | { 117 | private $description; 118 | 119 | public function __construct($description) { 120 | $this->description = $description; 121 | } 122 | 123 | public function on() { 124 | echo($this->description . " on"); 125 | echo("
"); 126 | } 127 | 128 | public function off() { 129 | echo($this->description . " off"); 130 | echo("
"); 131 | } 132 | 133 | public function dim($level) { 134 | echo($this->description . " dimming to " . $level . "%"); 135 | echo("
"); 136 | } 137 | } 138 | 139 | 140 | class CDPlayer 141 | { 142 | private $amplifier; 143 | private $description; 144 | private $currentTrack; 145 | private $title; 146 | 147 | public function __construct(Amplifier $amplifier, $description) { 148 | $this->amplifier = $amplifier; 149 | $this->description = $description; 150 | } 151 | 152 | public function on() { 153 | echo($this->description . " on"); 154 | echo("
"); 155 | } 156 | 157 | public function off() { 158 | echo($this->description . " off"); 159 | echo("
"); 160 | 161 | } 162 | 163 | public function eject() { 164 | $this->title = null; 165 | echo($this->description . " eject"); 166 | echo("
"); 167 | } 168 | 169 | public function play($titleOrTrack) { 170 | if (is_string($titleOrTrack)) { 171 | $this->title = $titleOrTrack; 172 | $this->currentTrack = 0; 173 | echo($this->description . " playing " . $this->title); 174 | echo("
"); 175 | } else { 176 | if($titleOrTrack == null) { 177 | echo($this->description . " can't play track " . $this->currentTrack . ", no cd inserted"); 178 | echo("
"); 179 | } else { 180 | $this->currentTrack = $titleOrTrack; 181 | echo($this->description . " playing track " . $this->currentTrack); 182 | echo("
"); 183 | } 184 | } 185 | } 186 | 187 | public function stop() { 188 | $this->currentTrack = 0; 189 | echo($this->description . " stopped"); 190 | echo("
"); 191 | } 192 | 193 | public function pause(){ 194 | echo($this->description . " paused " . $this->title); 195 | echo("
"); 196 | } 197 | 198 | public function __toString() { 199 | return $this->description; 200 | } 201 | } 202 | 203 | // DVD播放機 204 | class DVDPlayer { 205 | 206 | private $amplifier; 207 | private $description; 208 | private $currentTrack; 209 | private $movie; 210 | 211 | public function __construct($description, Amplifier $amplifier) { 212 | $this->amplifier = $amplifier; 213 | $this->description = $description; 214 | } 215 | 216 | public function on() { 217 | echo($this->description . " on"); 218 | echo("
"); 219 | } 220 | 221 | public function off() { 222 | echo($this->description . " off"); 223 | echo("
"); 224 | } 225 | 226 | public function eject() { 227 | $this->movie = null; 228 | echo($this->description . " eject"); 229 | echo("
"); 230 | } 231 | 232 | public function play($movieOrTrack) { 233 | if (is_string($movieOrTrack)) { 234 | $this->movie = $movieOrTrack; 235 | $this->currentTrack = 0; 236 | echo($this->description . " playing " . $this->movie); 237 | } else { 238 | if ($this->movie == null) { 239 | echo($this->description . " can't play track " . $movieOrTrack . " no dvd inserted"); 240 | } else { 241 | $this->currentTrack = $movieOrTrack; 242 | echo(description . " playing track " . $this->currentTrack . " of " . $this->movie); 243 | } 244 | } 245 | } 246 | 247 | public function stop() { 248 | $this->currentTrack = 0; 249 | echo($this->description . " stopped"); 250 | echo("
"); 251 | } 252 | 253 | public function pause() { 254 | echo($this->description . " paused " . $this->movie); 255 | echo("
"); 256 | } 257 | 258 | public function setTwoChannelAudio() { 259 | echo($this->description . " set two channel audio"); 260 | echo("
"); 261 | } 262 | 263 | public function setSurroundAudio() { 264 | echo($this->description . " set surround audio"); 265 | echo("
"); 266 | } 267 | 268 | public function __toString() { 269 | return $this->description; 270 | } 271 | } 272 | 273 | 274 | 275 | 276 | // 螢幕 277 | class Screen 278 | { 279 | private $description; 280 | 281 | public function __construct($description) { 282 | $this->description = $description; 283 | } 284 | 285 | public function up() { 286 | echo($this->description . " going up"); 287 | echo("
"); 288 | } 289 | 290 | public function down() { 291 | echo($this->description . " going down"); 292 | echo("
"); 293 | } 294 | } 295 | 296 | 297 | // 投影機 298 | class Projector 299 | { 300 | private $description; 301 | private $dvdPlayer; 302 | 303 | public function __construct($description, DVDPlayer $dvdPlayer) { 304 | $this->description = $description; 305 | $this->dvdPlayer = $dvdPlayer; 306 | } 307 | 308 | public function on() { 309 | echo($this->description . " on"); 310 | echo("
"); 311 | } 312 | 313 | public function off() { 314 | echo($this->description . " off"); 315 | echo("
"); 316 | } 317 | 318 | public function wideScreenMode() { 319 | echo($this->description . " in widescreen mode (16x9 aspect ratio)"); 320 | echo("
"); 321 | } 322 | 323 | public function tvMode() { 324 | echo($this->description . " in tv mode (4x3 aspect ratio)"); 325 | echo("
"); 326 | } 327 | 328 | } 329 | 330 | 331 | 332 | // 音響擴大機 333 | class Amplifier 334 | { 335 | private $tuner; 336 | private $dvd; 337 | private $cd; 338 | private $description; 339 | 340 | public function __construct($description) { 341 | $this->description = $description; 342 | } 343 | 344 | public function on() { 345 | echo($this->description . " on"); 346 | echo("
"); 347 | } 348 | 349 | public function off() { 350 | echo($this->description . " off"); 351 | echo("
"); 352 | } 353 | 354 | public function setCD(CDPlayer $cd) { 355 | echo($this->description . " setting CD player to " . $cd); 356 | echo("
"); 357 | $this->cd = $cd; 358 | } 359 | 360 | public function setDVD(DVDPlayer $dvd) { 361 | echo($this->description . " setting DVD player to " . $dvd); 362 | echo("
"); 363 | $this->dvd = $dvd; 364 | } 365 | 366 | public function setStereoSound() { 367 | echo($this->description . " stereo mode on"); 368 | echo("
"); 369 | } 370 | 371 | public function setSurroundSound() { 372 | echo($this->description . " surround sound on (5 speakers, 1 subwoofer)"); 373 | echo("
"); 374 | } 375 | 376 | public function setTuner(Tuner $tuner) { 377 | echo($this->description . " setting tuner to " . $this->dvd); 378 | echo("
"); 379 | $this->tuner = $tuner; 380 | } 381 | 382 | public function setVolume($volume) { 383 | echo($this->description . " setting volume to " . $volume); 384 | echo("
"); 385 | } 386 | } 387 | 388 | 389 | 390 | class HomeTheaterFacade 391 | { 392 | private $amplifier; 393 | private $tuner; 394 | private $dvd; 395 | private $cd; 396 | private $projector; 397 | private $lights; 398 | private $screen; 399 | 400 | public function __construct(Amplifier $amplifier, Tuner $tuner, DVDPlayer $dvd, CDPlayer $cd, Projector $projector, Screen $screen, TheaterLights $lights) { 401 | $this->amplifier = $amplifier; 402 | $this->tuner = $tuner; 403 | $this->dvd = $dvd; 404 | $this->cd = $cd; 405 | $this->projector = $projector; 406 | $this->screen = $screen; 407 | $this->lights = $lights; 408 | } 409 | 410 | public function watchMovie($movie) { 411 | echo "Get ready to watch a movie...
"; 412 | $this->lights->on(); 413 | $this->lights->dim(10); 414 | $this->screen->down(); 415 | $this->projector->on(); 416 | $this->projector->wideScreenMode(); 417 | $this->amplifier->on(); 418 | $this->amplifier->setDVD($this->dvd); 419 | $this->amplifier->setSurroundSound(); 420 | $this->amplifier->setVolume(5); 421 | $this->dvd->on(); 422 | $this->dvd->play($movie); 423 | } 424 | } 425 | 426 | ?> 427 | -------------------------------------------------------------------------------- /example/trunk/class/pattern/factory.php: -------------------------------------------------------------------------------- 1 |
"; 44 | } 45 | } 46 | 47 | // 士兵 48 | class Solider extends Unit 49 | { 50 | public function playSlogan() { 51 | echo "快給我戰鬥藥吧!!

"; 52 | } 53 | } 54 | 55 | // 飛機 56 | class Aircraft extends Unit 57 | { 58 | public function playSlogan() { 59 | echo "我已經準備好起飛出擊了,長官!

"; 60 | } 61 | } 62 | 63 | 64 | 65 | 66 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/flyweight.php: -------------------------------------------------------------------------------- 1 | char = $char; 15 | $this->size = $size; 16 | $this->color = $color; 17 | $this->posX = $posX; 18 | $this->posY = $posY; 19 | } 20 | 21 | public function showChar() { 22 | echo $this->char . " size:" . $this->size . " color:" . $this->color 23 | . " (" . $this->posX . "," . $this->posY . ")
"; 24 | } 25 | } 26 | 27 | 28 | // Flyweight 29 | interface Flyweight 30 | { 31 | // 設置內外狀態關係連結的方法 32 | public function showChar($size, $color, $posX, $posY); 33 | } 34 | 35 | // ConcreteFlyweight 36 | class Character implements Flyweight 37 | { 38 | private $char = null; // intrinsicState 39 | public function __construct($char) { 40 | $this->char = $char; 41 | } 42 | 43 | // Operation 44 | public function showChar($size, $color, $posX, $posY) { 45 | echo $this->char . " size:" . $size . " color:" . $color 46 | . " (" . $posX . "," . $posY . ")
"; 47 | } 48 | 49 | } 50 | 51 | class FlyweightFactory 52 | { 53 | private $flyweights; 54 | 55 | public function __construct() { 56 | $this->flyweights = array(); 57 | } 58 | 59 | public function getFlyweight($char) { 60 | if (isset($this->flyweights[$char])) { 61 | return $this->flyweights[$char]; 62 | } else { 63 | return $this->flyweights[$char] = new Character($char); 64 | } 65 | } 66 | } 67 | 68 | 69 | 70 | /* 71 | // Flyweight 72 | abstract class Flyweight 73 | { 74 | abstract public function operation($extrinasicState); 75 | } 76 | 77 | // ConcreteFlyweight 78 | class ConcreteFlyweight extends Flyweight 79 | { 80 | private $intrinsicState = null; 81 | public function __construct($intrinsicState) { 82 | $this->intrinsicState = $intrinsicState; 83 | } 84 | 85 | public function operation($extrinasicState) { 86 | echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->intrinsicState 87 | . ' Extrinsic State = ' . $extrinasicState . '
'; 88 | } 89 | } 90 | 91 | 92 | class FlyweightFactory 93 | { 94 | private $flyweights; 95 | 96 | public function __construct() { 97 | $this->flyweights = array(); 98 | } 99 | 100 | public function getFlyweight($state) { 101 | if (isset($this->flyweights[$state])) { 102 | return $this->flyweights[$state]; 103 | } else { 104 | return $this->flyweights[$state] = new ConcreteFlyweight($state); 105 | } 106 | } 107 | } 108 | 109 | 110 | // UnsharedConcreteFlyweight 111 | class UnsharedConcreteFlyweight extends Flyweight 112 | { 113 | private $flyweights; 114 | public function __construct() { 115 | $this->flyweights = array(); 116 | } 117 | 118 | public function operation($state) { 119 | foreach ($this->flyweights as $flyweight) { 120 | $flyweight->operation($state); 121 | } 122 | } 123 | 124 | public function add($state, Flyweight $flyweight) { 125 | $this->flyweights[$state] = $flyweight; 126 | } 127 | } 128 | 129 | 130 | class FlyweightFactory 131 | { 132 | private $flyweights; 133 | public function __construct() { 134 | $this->flyweights = array(); 135 | } 136 | 137 | public function getFlyweight($state) { 138 | 139 | if (is_array($state)) { // Unshared 140 | 141 | $uFlyweight = new UnsharedConcreteFlyweight(); 142 | 143 | foreach ($state as $row) { 144 | $uFlyweight->add($row, $this->getFlyweight($row)); 145 | } 146 | 147 | return $uFlyweight; 148 | 149 | } else if (is_string($state)) { 150 | 151 | if (isset($this->_flyweights[$state])) { 152 | return $this->_flyweights[$state]; 153 | } else { 154 | return $this->_flyweights[$state] = new ConcreteFlyweight($state); 155 | } 156 | 157 | } else { 158 | return null; 159 | } 160 | } 161 | } 162 | */ 163 | 164 | 165 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/interpreter.php: -------------------------------------------------------------------------------- 1 | number = $number; 16 | } 17 | 18 | public function interpret() { 19 | return $this->number; 20 | } 21 | } 22 | 23 | // NonterminalExpression 24 | class AddExpression implements AbstractExpression 25 | { 26 | protected $leftExpression; 27 | protected $rightExpression; 28 | 29 | public function __construct($left, $right) { 30 | $this->leftExpression = $left; 31 | $this->rightExpression = $right; 32 | } 33 | 34 | public function interpret() { 35 | return $this->leftExpression->interpret() + $this->rightExpression->interpret(); 36 | } 37 | } 38 | 39 | // NonterminalExpression 40 | class SubtractExpression implements AbstractExpression 41 | { 42 | protected $leftExpression; 43 | protected $rightExpression; 44 | 45 | public function __construct($left, $right) { 46 | $this->leftExpression = $left; 47 | $this->rightExpression = $right; 48 | } 49 | 50 | public function interpret() { 51 | return $this->leftExpression->interpret() - $this->rightExpression->interpret(); 52 | } 53 | } 54 | 55 | // Context 56 | class Calculator 57 | { 58 | private $statement = ""; 59 | private $expression = null; 60 | 61 | public function build($statement) { 62 | $left = null; 63 | $right = null; 64 | $stack = array(); 65 | $statementArr = explode(" ", $statement); 66 | 67 | for ($i = 0, $statementArrCount = count($statementArr); $i < $statementArrCount; $i++) { 68 | 69 | if ($statementArr[$i] == "+") { 70 | $left = array_pop($stack); 71 | $val = $statementArr[++$i]; 72 | 73 | $right = new NumberExpression($val); 74 | $stack[] = new AddExpression($left, $right); 75 | 76 | } else if($statementArr[$i] == "-") { 77 | $left = array_pop($stack); 78 | $val = $statementArr[++$i]; 79 | 80 | $right = new NumberExpression($val); 81 | $stack[] = new SubtractExpression($left, $right); 82 | 83 | } else { 84 | $stack[] = new NumberExpression($statementArr[$i]); 85 | } 86 | } 87 | $this->expression = array_pop($stack); 88 | 89 | } 90 | 91 | public function compute() { 92 | return $this->expression->interpret(); 93 | } 94 | } 95 | 96 | 97 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/iterator.php: -------------------------------------------------------------------------------- 1 | units; 30 | } 31 | 32 | public function addUnit(Unit $unit) { //將一戰鬥單位加入到軍隊群組中 33 | if(in_Array($unit, $this->units, true)) { 34 | return; 35 | } 36 | $this->units[] = $unit; 37 | } 38 | 39 | public function removeUnit(Unit $unit) { //將一戰鬥單位從軍隊群組中移除 40 | //$this->units = array_udiff($this->units, array($unit), function($a, $b){ return ($a === $b)?0:1; }); //PHP 5.3寫法 41 | $this->units = array_udiff($this->units, array($unit), create_function('$a, $b', 'return ($a === $b)?0:1;')); 42 | } 43 | 44 | public function createIterator() { 45 | return new CompositeIterator($this); 46 | } 47 | 48 | } 49 | 50 | 51 | 52 | // ConcreteAggregate 53 | class Army extends CompositeUnit 54 | { 55 | public function getName() { 56 | echo '軍隊
'; 57 | } 58 | 59 | public function bombardStrength() { //計算總攻擊力 60 | $ret = 0; 61 | foreach( $this->units() as $unit) { 62 | $ret += $unit->bombardStrength(); 63 | } 64 | return $ret; 65 | } 66 | } 67 | 68 | // ConcreteAggregate 69 | class TroopCarrier extends CompositeUnit 70 | { 71 | public function getName() { 72 | echo '裝甲運兵車
'; 73 | } 74 | 75 | public function addUnit(Unit $unit) { //將單位加入 76 | 77 | if($unit instanceof Cavalry) { 78 | throw new Exception("Can't get a horse on the vehicle"); 79 | } 80 | parent::addUnit($unit); 81 | } 82 | 83 | public function bombardStrength() { 84 | return 15; 85 | } 86 | } 87 | 88 | 89 | // 弓箭手 90 | class Archer extends Unit 91 | { 92 | public function getName() { 93 | echo '弓箭手
'; 94 | } 95 | 96 | public function bombardStrength() { 97 | return 4; 98 | } 99 | } 100 | 101 | // 雷射加農砲 102 | class LaserCannonUnit extends Unit 103 | { 104 | public function getName() { 105 | echo '雷射加農砲
'; 106 | } 107 | 108 | public function bombardStrength() { 109 | return 44; 110 | } 111 | } 112 | 113 | // 騎兵 114 | class Cavalry extends Unit 115 | { 116 | public function getName() { 117 | echo '騎兵
'; 118 | } 119 | 120 | public function bombardStrength() { 121 | return 15; 122 | } 123 | } 124 | 125 | 126 | // Iterator 127 | interface MyIterator 128 | { 129 | public function next(); 130 | public function hasNext(); 131 | } 132 | 133 | // ConcreteIterator 134 | class CompositeIterator implements MyIterator 135 | { 136 | protected $units; 137 | protected $currentIndex = 0; 138 | 139 | public function __construct(CompositeUnit $compositeUnit) { 140 | $this->units = $compositeUnit->units(); 141 | } 142 | 143 | public function current() { 144 | return $this->units[$this->currentIndex]; 145 | } 146 | 147 | public function next() { 148 | if ($this->hasNext()) { 149 | $component = $this->units[$this->currentIndex]; 150 | $this->currentIndex++; 151 | return $component; 152 | } else { 153 | echo "沒有物件了喔!
"; 154 | } 155 | } 156 | 157 | public function hasNext() { 158 | 159 | if (empty($this->units) || !isset($this->units[$this->currentIndex])) { 160 | return false; 161 | } else { 162 | 163 | if (count($this->units) > $this->currentIndex) { 164 | return true; 165 | } else { 166 | return null; 167 | } 168 | 169 | } 170 | } 171 | } 172 | 173 | 174 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/mediator.php: -------------------------------------------------------------------------------- 1 | copyBtn = $copyBtn; 13 | $this->clearBtn = $clearBtn; 14 | $this->parentList = $parentList; 15 | $this->childList = $childList; 16 | } 17 | 18 | // 按下複製按鈕 19 | public function copyBtnClick() { 20 | 21 | if($this->copyBtn->getStatus() == 1) 22 | echo "複製按鈕按下
"; 23 | else 24 | echo "複製按鈕目前禁用中
"; 25 | } 26 | 27 | // 按下清除按鈕 28 | public function clearBtnClick() { 29 | if ($this->clearBtn->getStatus() == 1) { 30 | $this->childList->clearData(); 31 | $this->copyBtn->setStatus(2); // 將Copy按鈕設為disabled 32 | $this->clearBtn->setStatus(2); // 將Clear按鈕設為disabled 33 | echo "清除按鈕按下,已將子列表的內容清除!
"; 34 | } else { 35 | echo "清除按鈕目前禁用中
"; 36 | } 37 | } 38 | 39 | // 選擇ParentList的項目 40 | public function selectParentData($count) { 41 | $data = $this->parentList->getData(); 42 | $this->childList->setData($data[$count]); 43 | $this->copyBtn->setStatus(1); // 將Copy按鈕設為enabled 44 | $this->clearBtn->setStatus(2); // 將Clear按鈕設為disabled 45 | 46 | echo "母項目選擇了" . $count . ",以下是子項目列表:
"; 47 | $this->childList->showData(); 48 | echo "
"; 49 | } 50 | 51 | // 選擇ChildList的項目 52 | public function selectChildData($count) { 53 | $this->clearBtn->setStatus(1); // 將Clear按鈕設為enabled 54 | echo "子項目選擇了".$count."
"; 55 | } 56 | } 57 | 58 | 59 | // Colleague 60 | abstract class Colleague 61 | { 62 | protected $mediator = null; 63 | protected $name = ""; 64 | protected $status = 2; //1:enabled. 2:disabled 65 | 66 | 67 | public function setStatus($status) { 68 | $this->status = $status; 69 | } 70 | 71 | public function getStatus() { 72 | return $this->status; 73 | } 74 | 75 | public function setMediator(FormMediator $mediator) { 76 | $this->mediator = $mediator; 77 | } 78 | 79 | abstract public function execute(); 80 | } 81 | 82 | 83 | class CopyButton extends Colleague 84 | { 85 | public function execute() { 86 | $this->mediator->copyBtnClick(); 87 | } 88 | } 89 | 90 | class ClearButton extends Colleague 91 | { 92 | public function execute() { 93 | $this->mediator->clearBtnClick(); 94 | } 95 | } 96 | 97 | abstract class ListBox 98 | { 99 | protected $mediator = null; 100 | protected $list = array(); 101 | 102 | public function setMediator(FormMediator $mediator) { 103 | $this->mediator = $mediator; 104 | } 105 | 106 | public function setData($data) { 107 | $this->list = $data; 108 | } 109 | 110 | public function getData() { 111 | return $this->list; 112 | } 113 | 114 | public function showData() { 115 | print_r($this->list); 116 | } 117 | 118 | public function clearData() { 119 | $this->list = array(); 120 | } 121 | 122 | abstract public function select($count = 0); 123 | } 124 | 125 | class ParentListBox extends ListBox 126 | { 127 | public function select($count = 0) { 128 | $this->mediator->selectParentData($count); 129 | } 130 | } 131 | 132 | class ChildListBox extends ListBox 133 | { 134 | public function select($count = 0) { 135 | $this->mediator->selectChildData($count); 136 | } 137 | } 138 | 139 | 140 | 141 | 142 | 143 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/memento.php: -------------------------------------------------------------------------------- 1 | hp = $hp; 16 | $this->mp = $mp; 17 | $this->dex = $dex; 18 | $this->atk = $atk; 19 | $this->def = $def; 20 | } 21 | 22 | public function getHp() { 23 | return $this->hp; 24 | } 25 | 26 | public function getMp() { 27 | return $this->mp; 28 | } 29 | 30 | public function getDex() { 31 | return $this->dex; 32 | } 33 | 34 | public function getAtk() { 35 | return $this->atk; 36 | } 37 | 38 | public function getDef() { 39 | return $this->def; 40 | } 41 | 42 | public function setState($hp, $mp, $dex, $atk, $def) { 43 | $this->hp = $hp; 44 | $this->mp = $mp; 45 | $this->dex = $dex; 46 | $this->atk = $atk; 47 | $this->def = $def; 48 | } 49 | 50 | public function showState() { 51 | echo "角色當前狀態:
"; 52 | echo "體力:{$this->hp}
"; 53 | echo "魔力:{$this->mp}
"; 54 | echo "敏捷:{$this->dex}
"; 55 | echo "攻擊力:{$this->atk}
"; 56 | echo "防禦力:{$this->def}

"; 57 | } 58 | 59 | public function fight() { 60 | $this->hp = 0; 61 | $this->mp = 0; 62 | $this->dex = 0; 63 | $this->atk = 0; 64 | $this->def = 0; 65 | 66 | echo "開打,被魔王秒殺...
"; 67 | } 68 | } 69 | 70 | 71 | 72 | // 遊戲角色(Originator) 73 | class Role 74 | { 75 | private $hp = 0; // 體力 76 | private $mp = 0; // 魔力 77 | private $dex = 0; // 敏捷 78 | private $atk = 0; // 攻擊力 79 | private $def = 0; // 防禦力 80 | 81 | public function __construct($hp, $mp, $dex, $atk, $def) { 82 | $this->hp = $hp; 83 | $this->mp = $mp; 84 | $this->dex = $dex; 85 | $this->atk = $atk; 86 | $this->def = $def; 87 | } 88 | 89 | public function saveState() { 90 | return new Memento($this->hp, $this->mp, $this->dex, $this->atk, $this->def); 91 | } 92 | 93 | public function recoveryState(Memento $memento) { 94 | $this->hp = $memento->getHp(); 95 | $this->mp = $memento->getMp(); 96 | $this->dex = $memento->getDex(); 97 | $this->atk = $memento->getAtk(); 98 | $this->def = $memento->getDef(); 99 | } 100 | 101 | public function showState() { 102 | echo "角色當前狀態:
"; 103 | echo "體力:{$this->hp}
"; 104 | echo "魔力:{$this->mp}
"; 105 | echo "敏捷:{$this->dex}
"; 106 | echo "攻擊力:{$this->atk}
"; 107 | echo "防禦力:{$this->def}

"; 108 | } 109 | 110 | public function fight() 111 | { 112 | $this->hp = 0; 113 | $this->mp = 0; 114 | $this->dex = 0; 115 | $this->atk = 0; 116 | $this->def = 0; 117 | 118 | echo "開打,被魔王秒殺...
"; 119 | } 120 | } 121 | 122 | class Memento 123 | { 124 | private $hp = 0; // 體力 125 | private $mp = 0; // 魔力 126 | private $dex = 0; // 敏捷 127 | private $atk = 0; // 攻擊力 128 | private $def = 0; // 防禦力 129 | 130 | public function __construct($hp, $mp, $dex, $atk, $def) { 131 | $this->hp = $hp; 132 | $this->mp = $mp; 133 | $this->dex = $dex; 134 | $this->atk = $atk; 135 | $this->def = $def; 136 | } 137 | 138 | public function getHp() { 139 | return $this->hp; 140 | } 141 | 142 | public function getMp() { 143 | return $this->mp; 144 | } 145 | 146 | public function getDex() { 147 | return $this->dex; 148 | } 149 | 150 | public function getAtk() { 151 | return $this->atk; 152 | } 153 | 154 | public function getDef() { 155 | return $this->def; 156 | } 157 | } 158 | 159 | class Caretaker 160 | { 161 | private $memento; 162 | 163 | public function getMemento() { 164 | return $this->memento; 165 | } 166 | 167 | public function setMemento(Memento $memento) { 168 | $this->memento = $memento; 169 | } 170 | } 171 | 172 | 173 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/observer.php: -------------------------------------------------------------------------------- 1 | setStatus(self::LOGIN_ACCESS, $user, $ip); 22 | $ret = true; 23 | break; 24 | 25 | case 2: 26 | $this->setStatus(self::LOGIN_WRONG_PASS, $user, $ip); 27 | $ret = false; 28 | break; 29 | 30 | case 3: 31 | $this->setStatus(self::LOGIN_USER_UNKNOWN, $user, $ip); 32 | $ret = false; 33 | break; 34 | 35 | case 4: 36 | $this->setStatus(self::LOGIN_ERROR37, $user, $ip); 37 | $ret = false; 38 | break; 39 | } 40 | return $ret; 41 | 42 | // 如果客戶要求你將用戶登入的IP地址記到LOG中.. 43 | Logger::logIP($user, $ip, $this->getStatus()); 44 | 45 | 46 | // 如果客戶要求每次登入發生錯誤時,都要寄一封Email到管理員信箱中.. 47 | if (!$ret) { 48 | Notifier::mailWarning($user, $ip, $this->getStatus()); 49 | } 50 | } 51 | 52 | private function setStatus($status, $user ,$ip) { 53 | $this->status = array($status, $user, $ip); 54 | } 55 | 56 | public function getStatus() { 57 | return $this->status; 58 | } 59 | } 60 | 61 | // log紀錄類別 62 | class Logger 63 | { 64 | public static function logIP($user, $ip, $status) { 65 | echo "log user IP address
"; 66 | } 67 | } 68 | 69 | // 郵件發送類別 70 | class Notifier 71 | { 72 | public static function mailWarning($user, $ip, $status) { 73 | echo "mail Warning to admin
"; 74 | } 75 | } 76 | */ 77 | 78 | 79 | //如果直接在代碼中加入功能,會破壞我們的設計,Login類別很快會跟這些額外的程式碼緊緊地綁在一起, 80 | //最後會走上剪切黏代碼的開發道路..Orz 81 | 82 | 83 | //Observer的核心是把客戶元素從一個中心類別中分離開來。 84 | 85 | 86 | 87 | 88 | interface Observer 89 | { 90 | public function update(Subject $subject); 91 | } 92 | 93 | // 為了保持Observable接口的通用性,由Observer類別負責保證它們的主體是正確的類型 94 | abstract class LoginObserver implements Observer 95 | { 96 | private $login; 97 | 98 | public function __construct(Login $login) { 99 | $this->login = $login; 100 | $login->attach($this); 101 | } 102 | 103 | public function update(Subject $subject) { 104 | if ($subject === $this->login) { 105 | $this->doUpdate($subject); 106 | } 107 | } 108 | 109 | abstract function doUpdate(Login $login); 110 | } 111 | 112 | class SecurityMonitor extends LoginObserver 113 | { 114 | public function doUpdate(Login $login) { 115 | $status = $login->getStatus(); 116 | if ($status[0] == Login::LOGIN_WRONG_PASS) { 117 | // 發送郵件給系統管理員 118 | echo __CLASS__ . ": sending mail to sysadmin
"; 119 | } 120 | } 121 | } 122 | 123 | class GeneralLogger extends LoginObserver 124 | { 125 | public function doUpdate(Login $login) { 126 | $status = $login->getStatus(); 127 | // 紀錄登入log 128 | echo __CLASS__ . ":add login data to log
"; 129 | } 130 | } 131 | 132 | class PartnershipTool extends LoginObserver 133 | { 134 | public function doUpdate(Login $login) { 135 | $status = $login->getStatus(); 136 | echo __CLASS__ . ":set cookie if IP matches a list
"; 137 | } 138 | } 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | interface Subject 147 | { 148 | public function attach(Observer $observer); 149 | public function detach(Observer $observer); 150 | public function notify(); 151 | } 152 | 153 | class Login implements Subject 154 | { 155 | const LOGIN_USER_UNKNOWN = 1; 156 | const LOGIN_WRONG_PASS = 2; 157 | const LOGIN_ACCESS = 3; 158 | const LOGIN_ERROR37 = 4; 159 | 160 | private $status = array(); 161 | private $observers; 162 | 163 | public function __construct() { 164 | $this->observers = array(); 165 | } 166 | 167 | public function handleLogin($pass, $user, $ip) { 168 | switch(rand(1,4)) { 169 | case 1: 170 | $this->setStatus(self::LOGIN_ACCESS, $user, $ip); 171 | $ret = true; 172 | break; 173 | 174 | case 2: 175 | $this->setStatus(self::LOGIN_WRONG_PASS, $user, $ip); 176 | $ret = false; 177 | break; 178 | 179 | case 3: 180 | $this->setStatus(self::LOGIN_USER_UNKNOWN, $user, $ip); 181 | $ret = false; 182 | break; 183 | 184 | case 4: 185 | $this->setStatus(self::LOGIN_ERROR37, $user, $ip); 186 | $ret = false; 187 | break; 188 | } 189 | $this->notify(); 190 | return $ret; 191 | } 192 | 193 | private function setStatus($status, $user ,$ip) { 194 | $this->status = array($status, $user, $ip); 195 | } 196 | 197 | public function getStatus() { 198 | return $this->status; 199 | } 200 | 201 | public function attach(Observer $observer){ // 註冊觀察者 202 | $this->observers[] = $observer; 203 | } 204 | 205 | public function detach(Observer $observer){ // 解除註冊特定觀察者 206 | $newobservers = array(); 207 | foreach ($this->observers as $obs) { 208 | if ($obs !== $observer) { 209 | $newobservers[] = $obs; 210 | } 211 | } 212 | $this->observers = $newobservers; 213 | } 214 | 215 | public function notify(){ // 發出通知 216 | foreach ($this->observers as $obs) { 217 | $obs->update($this); 218 | } 219 | } 220 | } 221 | 222 | 223 | /* 224 | class Login implements SplSubject 225 | { 226 | const LOGIN_USER_UNKNOWN = 1; 227 | const LOGIN_WRONG_PASS = 2; 228 | const LOGIN_ACCESS = 3; 229 | const LOGIN_ERROR37 = 4; 230 | 231 | private $status = array(); 232 | private $storage; 233 | 234 | public function __contstuct() { 235 | $this->storage = new SplObjectStorage(); // PHP >= 5.3 236 | } 237 | 238 | 239 | public function handleLogin($pass, $user, $ip) { 240 | switch(rand(1,4)){ 241 | case 1: 242 | $this->setStatus(self::LOGIN_ACCESS, $user, $ip); 243 | $ret = true; 244 | break; 245 | 246 | case 2: 247 | $this->setStatus(self::LOGIN_WRONG_PASS, $user, $ip); 248 | $ret = false; 249 | break; 250 | 251 | case 3: 252 | $this->setStatus(self::LOGIN_USER_UNKNOWN, $user, $ip); 253 | $ret = false; 254 | break; 255 | 256 | case 4: 257 | $this->setStatus(self::LOGIN_ERROR37, $user, $ip); 258 | $ret = false; 259 | break; 260 | } 261 | $this->notify(); 262 | return $ret; 263 | } 264 | 265 | private function setStatus($status, $user ,$ip) { 266 | $this->status = array($status, $user, $ip); 267 | } 268 | 269 | public function getStatus() { 270 | return $this->status; 271 | } 272 | 273 | public function attach(SplObserver $observer) { 274 | $this->storage->attach($observer); 275 | } 276 | 277 | public function detach(SplObserver $observer) { 278 | $this->storage->detach($observer); 279 | } 280 | 281 | public function notify() { 282 | foreach($this->storage as $obs){ 283 | $obs->update($this); 284 | } 285 | } 286 | } 287 | 288 | 289 | // 為了保持Observable接口的通用性,由Observer類別負責保證它們的主體是正確的類型 290 | abstract class LoginObserver implements SplObserver 291 | { 292 | private $login; 293 | public function __construct(Login $login) { 294 | $this->login = $login; 295 | $login->attach($this); 296 | } 297 | 298 | public function update(SplSubject $subject) { 299 | if($subject === $this->login){ 300 | $this->doUpdate($subject); 301 | } 302 | } 303 | 304 | abstract function doUpdate(Login $login); 305 | } 306 | 307 | class SecurityMonitor extends LoginObserver 308 | { 309 | public function doUpdate(Login $login) { 310 | $status = $login->getStatus(); 311 | if ($status[0] == Login::LOGIN_WRONG_PASS) { 312 | // 發送郵件給系統管理員 313 | echo __CLASS__.": sending mail to sysadmin
"; 314 | } 315 | } 316 | } 317 | 318 | class GeneralLogger extends LoginObserver 319 | { 320 | public function doUpdate(Login $login) { 321 | $status = $login->getStatus(); 322 | // 紀錄登入log 323 | echo __CLASS__.":add login data to log
"; 324 | } 325 | } 326 | 327 | class PartnershipTool extends LoginObserver 328 | { 329 | public function doUpdate(Login $login) { 330 | $status = $login->getStatus(); 331 | echo __CLASS__.":set cookie if IP matches a list
"; 332 | } 333 | } 334 | */ 335 | 336 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/prototype.php: -------------------------------------------------------------------------------- 1 | instance = ++self::$instances; 13 | $this->value = $value; 14 | } 15 | public function __clone() { 16 | $this->instance = ++self::$instances; 17 | } 18 | 19 | public function showValue() { 20 | return $this->value . "
"; 21 | } 22 | } 23 | 24 | 25 | // Prototype 26 | abstract class BookPrototype 27 | { 28 | public $subObject1; 29 | public $subObject2; 30 | public $title; 31 | public $topic; 32 | 33 | public function __construct($obj1, $obj2, $title) { 34 | $this->subObject1 = $obj1; 35 | $this->subObject2 = $obj2; 36 | $this->title = $title; 37 | } 38 | // Deep Clone 39 | public function __clone() { 40 | // Force a copy of this->object, otherwise it will point to same object. 41 | $this->subObject1 = clone $this->subObject1; 42 | } 43 | 44 | public function setTitle($title) { 45 | $this->title = $title; 46 | } 47 | 48 | public function show() { 49 | echo $this->topic . " " . $this->title . "
" . 50 | "object1 Value: " . $this->subObject1->showValue() . 51 | "object2 Value: " . $this->subObject2->showValue(); 52 | } 53 | } 54 | 55 | 56 | // ConcretePrototype 57 | class NovelPrototype extends BookPrototype 58 | { 59 | public function __construct($obj1, $obj2, $title) { 60 | parent::__construct($obj1, $obj2, $title); 61 | $this->topic = "Novel"; 62 | } 63 | 64 | } 65 | 66 | // ConcretePrototype 67 | class ReferenceBookPrototype extends BookPrototype 68 | { 69 | public function __construct($obj1, $obj2, $title) { 70 | parent::__construct($obj1, $obj2, $title); 71 | $this->topic = "ReferenceBook"; 72 | } 73 | 74 | } 75 | 76 | 77 | 78 | 79 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/proxy.php: -------------------------------------------------------------------------------- 1 | "; 20 | } 21 | 22 | public function viewNote() { 23 | echo "查看內容!
"; 24 | } 25 | 26 | public function publishNote() { 27 | echo "發佈新訊息!
"; 28 | } 29 | 30 | public function modifyNote() { 31 | echo "修改發佈訊息內容!
"; 32 | } 33 | 34 | public function setLevel($level) { 35 | $this->level = $level; 36 | } 37 | 38 | public function getLevel() { 39 | return $this->level; 40 | } 41 | } 42 | 43 | // Proxy 44 | class PermissionProxy implements AbstractPermission 45 | { 46 | private $realPermission = null; 47 | 48 | public function __construct() { 49 | $this->realPermission = new RealPermission(); 50 | } 51 | 52 | public function modifyUserInfo() { 53 | 54 | if ($this->realPermission->getLevel() == 0) { 55 | echo "對不起,你沒有該權限!
"; 56 | } else { 57 | echo "開始修改用戶權限!
"; 58 | } 59 | } 60 | 61 | public function viewNote() { 62 | $this->realPermission->viewNote(); 63 | } 64 | 65 | public function publishNote() { 66 | if ($this->realPermission->getLevel() == 0) { 67 | echo "對不起,你沒有權限發佈新訊息!
"; 68 | } else { 69 | $this->realPermission->publishNote(); 70 | } 71 | } 72 | 73 | public function modifyNote() { 74 | if ($this->realPermission->getLevel() == 0) { 75 | echo "對不起,你沒有權限修改訊息!
"; 76 | } else { 77 | $this->realPermission->modifyNote(); 78 | } 79 | 80 | } 81 | 82 | public function setLevel($level) { 83 | $this->realPermission->setLevel($level); 84 | } 85 | 86 | } 87 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/simpleFactory.php: -------------------------------------------------------------------------------- 1 | getMaterial(); 33 | $unit->train(); 34 | $unit->create(); 35 | 36 | return $unit; 37 | } 38 | } 39 | 40 | 41 | // 抽象單位 42 | abstract class Unit 43 | { 44 | public abstract function getMaterial(); // 取得材料 45 | public abstract function train(); // 訓練 46 | public abstract function create(); // 產生 47 | } 48 | 49 | // 工人 50 | class Worker extends Unit 51 | { 52 | public function getMaterial() { 53 | echo "使用了50單位的水晶
"; 54 | } 55 | 56 | public function train() { 57 | echo "訓練時間10秒
"; 58 | } 59 | 60 | 61 | public function create() { 62 | echo "I am a Worker, I am ready to work!

"; 63 | } 64 | } 65 | 66 | // 士兵 67 | class Solider extends Unit 68 | { 69 | public function getMaterial() { 70 | echo "使用了50單位的水晶、10單位的瓦斯
"; 71 | } 72 | 73 | public function train() { 74 | echo "訓練時間20秒
"; 75 | } 76 | 77 | public function create() { 78 | echo "I am a Solider, Waiting for your order!

"; 79 | } 80 | } 81 | 82 | 83 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/singleton.php: -------------------------------------------------------------------------------- 1 | props[$key] = $val; 21 | } 22 | 23 | public function getProperty( $key ) { 24 | return $this->props[$key]; 25 | } 26 | } 27 | 28 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/state.php: -------------------------------------------------------------------------------- 1 | count = $count; 21 | 22 | if ($this->count > 0) { 23 | $this->state = CandyMachine::STATUS_NO_COIN; 24 | } else { 25 | $this->state = CandyMachine::STATUS_SOLDOUT; 26 | } 27 | 28 | echo "初始化糖果機成功,共有" . $count . "顆糖果
"; 29 | } 30 | 31 | // 取得目前剩餘糖果數量 32 | public function getCount() { 33 | return $this->count; 34 | } 35 | 36 | public function setState($state){ 37 | $this->state = $state; 38 | } 39 | 40 | public function getState(){ 41 | return $this->state; 42 | } 43 | 44 | 45 | public function releaseCandy() { 46 | if ( $this->count > 0 ) { 47 | $this->count = $this->count - 1; 48 | echo "得到一顆糖果,還有有糖果 {$this->count} 顆
"; 49 | } 50 | } 51 | 52 | // 插入硬幣 53 | public function insertCoin() { 54 | switch($this->state) { 55 | case CandyMachine::STATUS_NO_COIN: 56 | $this->setState(CandyMachine::STATUS_HAS_COIN); 57 | echo "你插入了一枚硬幣
"; 58 | break; 59 | 60 | case CandyMachine::STATUS_HAS_COIN: 61 | echo "已經有硬幣了,無法插入
"; 62 | break; 63 | 64 | case CandyMachine::STATUS_SOLD: 65 | echo "請稍等,我們正在給你糖果
"; 66 | break; 67 | 68 | case CandyMachine::STATUS_SOLDOUT: 69 | echo "很抱歉,所有糖果都已售鑿,無法插入
"; 70 | break; 71 | } 72 | } 73 | 74 | // 退回硬幣 75 | public function ejectCoin() { 76 | switch($this->state) { 77 | case CandyMachine::STATUS_NO_COIN: 78 | echo "你還沒插入硬幣呢!
"; 79 | break; 80 | 81 | case CandyMachine::STATUS_HAS_COIN: 82 | $this->setState(CandyMachine::STATUS_NO_COIN); 83 | echo "退回硬幣
"; 84 | break; 85 | 86 | case CandyMachine::STATUS_SOLD: 87 | echo "很抱歉,你已經轉動了曲柄,無法退回
"; 88 | break; 89 | 90 | case CandyMachine::STATUS_SOLDOUT: 91 | echo "所有糖果已售鑿,無法插入硬幣,故不退幣
"; 92 | break; 93 | } 94 | } 95 | 96 | // 轉動曲柄 97 | public function turnCrank() { 98 | switch($this->state){ 99 | case CandyMachine::STATUS_NO_COIN: 100 | echo "你還沒插入硬幣,無法轉動曲柄
"; 101 | break; 102 | 103 | case CandyMachine::STATUS_HAS_COIN: 104 | 105 | if ($this->count > 0){ 106 | $this->setState(CandyMachine::STATUS_SOLD); 107 | echo "你轉動了曲柄
"; 108 | } else { 109 | $this->setState(CandyMachine::STATUS_SOLDOUT); 110 | echo "你轉動了曲柄,但是已經沒有糖果了
"; 111 | } 112 | 113 | break; 114 | 115 | case CandyMachine::STATUS_SOLD: 116 | echo "很抱歉,你正在轉動曲柄,所以此命令無效
"; 117 | break; 118 | 119 | case CandyMachine::STATUS_SOLDOUT: 120 | echo "很抱歉,已經沒有糖果了,無法轉動曲柄
"; 121 | break; 122 | } 123 | } 124 | 125 | // 發放糖果 126 | public function dispense() { 127 | switch($this->state){ 128 | case CandyMachine::STATUS_NO_COIN: 129 | echo "你還沒插入硬幣,無法發放糖果
"; 130 | break; 131 | 132 | case CandyMachine::STATUS_HAS_COIN: 133 | echo "請先轉動曲柄
"; 134 | break; 135 | 136 | case CandyMachine::STATUS_SOLD: 137 | $this->releaseCandy(); 138 | if($this->count > 0) 139 | $this->setState(CandyMachine::STATUS_NO_COIN); 140 | else { 141 | $this->setState(CandyMachine::STATUS_SOLDOUT); 142 | echo "没有糖果了.\n"; 143 | } 144 | break; 145 | 146 | case CandyMachine::STATUS_SOLDOUT: 147 | echo "很抱歉,已經沒有糖果了,無法發放
"; 148 | break; 149 | } 150 | } 151 | } 152 | */ 153 | 154 | 155 | class CandyMachine 156 | { 157 | private $noCoinState; 158 | private $hasCoinState; 159 | private $soldState; 160 | private $soldoutState; 161 | private $doubleState; // 送兩顆糖果狀態 162 | 163 | private $state; // 糖果機目前狀態 164 | private $count = 0; // 糖果數量 165 | 166 | public function __construct( $count = 0) { 167 | $this->noCoinState = new NoCoinState($this); 168 | $this->hasCoinState = new HasCoinState($this); 169 | $this->soldState = new SoldState($this); 170 | $this->soldoutState = new SoldoutState($this); 171 | $this->doubleState = new DoubleState($this); // 多初始化送兩顆糖果的狀態 172 | $this->count = $count; 173 | 174 | if($this->count > 0) { 175 | $this->state = $this->noCoinState; 176 | } else { 177 | $this->state = $this->soldoutState; 178 | } 179 | 180 | echo "初始化糖果機成功,共有".$count."顆糖果
"; 181 | } 182 | 183 | // 取得目前剩餘糖果數量 184 | public function getCount() { 185 | return $this->count; 186 | } 187 | 188 | public function setState(State $state) { 189 | $this->state = $state; 190 | } 191 | 192 | public function getState() { 193 | return $this->state; 194 | } 195 | 196 | public function releaseCandy() { 197 | if ( $this->count > 0 ) { 198 | $this->count = $this->count - 1; 199 | echo "得到一顆糖果,还有糖果 {$this->count} 顆
"; 200 | } 201 | } 202 | 203 | public function insertCoin() { 204 | $this->state->insertCoin(); 205 | } 206 | 207 | public function ejectCoin() { 208 | $this->state->ejectCoin(); 209 | } 210 | 211 | public function turnCrank() { 212 | $this->state->turnCrank(); 213 | } 214 | 215 | public function dispense() { 216 | $this->state->dispense(); 217 | } 218 | 219 | public function getNoCoinState () { 220 | return $this->noCoinState; 221 | } 222 | 223 | public function getHasCoinState () { 224 | return $this->hasCoinState; 225 | } 226 | 227 | public function getSoldOutState () { 228 | return $this->soldoutState; 229 | } 230 | 231 | public function getSoldState () { 232 | return $this->soldState; 233 | } 234 | 235 | public function getDoubleState() { 236 | return $this->doubleState; 237 | } 238 | } 239 | 240 | 241 | // 狀態模式 242 | interface State 243 | { 244 | public function insertCoin(); // 插入硬幣 245 | public function ejectCoin(); // 退回硬幣 246 | public function turnCrank(); // 轉動曲柄 247 | public function dispense(); // 發放糖果 248 | } 249 | 250 | class NoCoinState implements State 251 | { 252 | private $machine; 253 | 254 | public function __construct(CandyMachine $candyMachine) { 255 | $this->machine = $candyMachine; 256 | } 257 | 258 | public function insertCoin() { 259 | $this->machine->setState($this->machine->getHasCoinState()); 260 | echo "你插入了一枚硬幣
"; 261 | } 262 | 263 | public function ejectCoin() { 264 | echo "沒插入硬幣,無法退回
"; 265 | } 266 | 267 | public function turnCrank() { 268 | echo "你還沒插入硬幣,無法轉動曲柄
"; 269 | } 270 | 271 | public function dispense() { 272 | echo "你還沒插入硬幣,無法發放糖果
"; 273 | } 274 | } 275 | 276 | class HasCoinState implements State 277 | { 278 | private $machine; 279 | 280 | public static function random() { // 亂數計算是否可以獲得兩顆糖果 281 | if(rand(1,10) == 1) { 282 | return true; 283 | } else { 284 | return false; 285 | } 286 | } 287 | 288 | public function __construct(CandyMachine $candyMachine) { 289 | $this->machine = $candyMachine; 290 | } 291 | 292 | public function insertCoin() { 293 | echo "已經有硬幣了,無法插入
"; 294 | } 295 | 296 | public function ejectCoin() { 297 | $this->machine->setState($this->machine->getNoCoinState()); 298 | echo "退回硬幣
"; 299 | } 300 | 301 | public function turnCrank() { 302 | if(self::random() == true) { 303 | $this->machine->setState($this->machine->getSoldState()); 304 | } else { 305 | $this->machine->setState($this->machine->getDoubleState()); // 變為兩顆糖果狀態 306 | } 307 | echo "你轉動了曲柄
"; 308 | } 309 | 310 | public function dispense() { 311 | echo "你還沒轉動曲柄,無法發放糖果
"; 312 | } 313 | } 314 | 315 | 316 | class SoldState implements State 317 | { 318 | private $machine; 319 | 320 | public function __construct(CandyMachine $candyMachine) { 321 | $this->machine = $candyMachine; 322 | } 323 | 324 | public function insertCoin() { 325 | echo "請稍等,我們正在給你糖果
"; 326 | } 327 | 328 | public function ejectCoin() { 329 | echo "很抱歉,你已經轉動了曲柄,無法退回
"; 330 | } 331 | 332 | public function turnCrank() { 333 | echo "很抱歉,你已經轉動曲柄,不能再轉了
"; 334 | } 335 | 336 | public function dispense() { 337 | $this->machine->releaseCandy(); 338 | if ( $this->machine->getCount() > 0 ) { 339 | $this->machine->setState($this->machine->getNoCoinState()); 340 | } else { 341 | echo "没有糖果了
"; 342 | $this->machine->setState($this->machine->getSoldOutState()); 343 | } 344 | } 345 | } 346 | 347 | 348 | class SoldoutState implements State 349 | { 350 | private $machine; 351 | 352 | public function __construct(CandyMachine $candyMachine) { 353 | $this->machine = $candyMachine; 354 | } 355 | 356 | public function insertCoin() { 357 | echo "很抱歉,所有糖果都已售鑿,無法插入
"; 358 | } 359 | 360 | public function ejectCoin() { 361 | echo "所有糖果已售鑿,無法插入硬幣,故不退幣
"; 362 | } 363 | 364 | public function turnCrank() { 365 | echo "很抱歉,已經沒有糖果了,無法轉動曲柄
"; 366 | } 367 | 368 | public function dispense() { 369 | echo "很抱歉,已經沒有糖果了,無法發放
"; 370 | } 371 | } 372 | 373 | // 兩顆糖果狀態 374 | class DoubleState implements State 375 | { 376 | private $machine; 377 | 378 | public function __construct(CandyMachine $candyMachine) { 379 | $this->machine = $candyMachine; 380 | } 381 | 382 | public function insertCoin() { 383 | echo "請稍等,我們正在給你糖果
"; 384 | } 385 | 386 | public function ejectCoin() { 387 | echo "很抱歉,你已經轉動了曲柄,無法退回
"; 388 | } 389 | 390 | public function turnCrank() { 391 | echo "很抱歉,你已經轉動曲柄,不能再轉了
"; 392 | } 393 | 394 | public function dispense() { 395 | $this->machine->releaseCandy(); 396 | if ( $this->machine->getCount() > 0 ) { 397 | 398 | echo "免費贈送一顆糖果
"; 399 | $this->machine->releaseCandy(); // 如果還有糖果,再發一顆 400 | 401 | if ( $this->machine->getCount() > 0 ) 402 | $this->machine->setState( $this->machine->getNoCoinState() ); 403 | else { 404 | echo "免費贈送一顆糖果,但是機器裡面没有糖果了
"; 405 | $this->machine->setState( $this->machine->getSoldOutState() ); 406 | } 407 | } else { 408 | echo "没有糖果了
"; 409 | $this->machine->setState( $this->machine->getSoldOutState() ); 410 | } 411 | } 412 | } 413 | 414 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/strategy.php: -------------------------------------------------------------------------------- 1 | Name = $name; 12 | $this->Mp = $mp; 13 | $this->Strategy = $strategy; 14 | } 15 | 16 | // 使用兵法 17 | public function useStrategy() { 18 | return $this->Name . " 使用了" . $this->Strategy->StrategyName() . ", " . $this->Strategy->useStrategy($this); 19 | } 20 | 21 | public function setStractegy(Strategy $strategy) { 22 | $this->Strategy = $strategy; 23 | } 24 | 25 | public function getMp(){ 26 | return $this->Mp; 27 | } 28 | 29 | public function setMp($mp){ 30 | $this->Mp = $mp; 31 | } 32 | } 33 | 34 | 35 | 36 | abstract class Strategy 37 | { 38 | abstract function useStrategy(Officer $officer); 39 | abstract function StrategyName(); 40 | } 41 | 42 | // 火牛陣 43 | class FireBullStrategy extends Strategy 44 | { 45 | public function useStrategy(Officer $officer) { 46 | $mp = $officer->getMp() - 10; 47 | $officer->setMp($mp); 48 | return '敵方受到 30 點傷害,並且造成混亂,還剩 '. $mp . ' 點MP'; 49 | } 50 | 51 | public function StrategyName() { 52 | return "火牛陣"; 53 | } 54 | } 55 | 56 | // 嘲弄術 57 | class ScoffStrategy extends Strategy { 58 | public function useStrategy(Officer $officer) { 59 | $mp = $officer->getMp() - 5; 60 | $officer->setMp($mp); 61 | return '敵方士氣下降 15 點,還剩 ' . $mp . ' 點MP'; 62 | } 63 | 64 | public function StrategyName() { 65 | return "嘲弄術"; 66 | } 67 | } 68 | 69 | 70 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/templateMethod.php: -------------------------------------------------------------------------------- 1 | openFile(); 8 | $this->readFile(); 9 | 10 | // 這邊加上了hook, 讓子類別可以決定是不是要在演算法中使用parserFile() 11 | if ($this->hook() == true) { 12 | $this->parseFile(); 13 | } 14 | 15 | $this->showFile(); 16 | $this->closeFile(); 17 | } 18 | 19 | // 共同的實現部分可以放在父類別, 避免程式碼重複 20 | protected function openFile() { 21 | echo "開啓檔案
"; 22 | } 23 | 24 | protected abstract function readFile(); // primitiveOperation() 25 | protected abstract function parseFile(); // primitiveOperation() 26 | protected abstract function showFile(); // primitiveOperation() 27 | protected abstract function closeFile(); // primitiveOperation() 28 | 29 | protected function hook() { // Hook方法 30 | return true; 31 | } 32 | } 33 | 34 | class WordTextReader extends TextReader 35 | { 36 | protected function readFile() { 37 | echo "讀取Word .doc格式檔案
"; 38 | } 39 | 40 | protected function parseFile() { 41 | echo "解析Word .doc格式檔案
"; 42 | } 43 | 44 | protected function showFile() { 45 | echo "顯示Word .doc格式檔案
"; 46 | } 47 | 48 | protected function closeFile() { 49 | echo "關閉Word .doc格式檔案
"; 50 | } 51 | } 52 | 53 | class AdobeTextReader extends TextReader 54 | { 55 | protected function readFile() { 56 | echo "讀取Adobe .pdf格式檔案
"; 57 | } 58 | 59 | protected function parseFile() { 60 | echo ""; 61 | } 62 | 63 | protected function showFile() { 64 | echo "顯示Adobe .pdf格式檔案
"; 65 | } 66 | 67 | protected function closeFile() { 68 | echo "顯示Adobe .pdf格式檔案
"; 69 | } 70 | 71 | // 覆寫了父類別的Hook 72 | protected function hook() { 73 | return false; 74 | } 75 | } 76 | ?> -------------------------------------------------------------------------------- /example/trunk/class/pattern/visitor.php: -------------------------------------------------------------------------------- 1 | visit($node); 10 | } 11 | 12 | public function visitCavalry(Cavalry $node) { 13 | $this->visit($node); 14 | } 15 | 16 | public function visitLaserCannonUnit(LaserCannonUnit $node) { 17 | $this->visit($node); 18 | } 19 | 20 | public function visitTroopCarrierUnit(TroopCarrierUnit $node) { 21 | $this->visit($node); 22 | } 23 | 24 | public function visitArmy(Army $node) { 25 | $this->visit($node); 26 | } 27 | } 28 | 29 | class TextDumpArmyVisitor extends ArmyVisitor 30 | { 31 | private $text = ""; 32 | 33 | public function visit(Unit $node) { 34 | $ret = ""; 35 | $pad = $node->getDepth(); 36 | $ret .= "({$pad})"; 37 | $ret .= get_class($node) . " : "; 38 | $ret .= "bombard: " . $node->bombardStrength() . "
"; 39 | $this->text .= $ret; 40 | } 41 | 42 | public function getText() { 43 | return $this->text; 44 | } 45 | } 46 | 47 | class TaxCollectionVisitor extends ArmyVisitor 48 | { 49 | private $due = 0; 50 | private $report = ""; 51 | 52 | public function visit(Unit $node) { 53 | $this->levy($node, 1); 54 | } 55 | 56 | public function visitArcher(Archer $node) { 57 | $this->levy($node, 2); 58 | } 59 | 60 | public function visitCavalry(Cavalry $node) { 61 | $this->levy($node, 3); 62 | } 63 | 64 | public function visitTroopCarrierUnit(TroopCarrierUnit $node) { 65 | $this->levy($node, 5); 66 | } 67 | 68 | private function levy(Unit $unit, $amount) { 69 | $this->report .= "Tax levied for " . get_class($unit); 70 | $this->report .= ": " . $amount . "
"; 71 | $this->due += $amount; 72 | } 73 | 74 | public function getReport() { 75 | return $this->report; 76 | } 77 | 78 | public function getTax() { 79 | return $this->due; 80 | } 81 | } 82 | 83 | 84 | 85 | abstract class Unit 86 | { 87 | private $depth = 0; 88 | 89 | public function getComposite() { 90 | return null; 91 | } 92 | 93 | abstract function bombardStrength(); 94 | 95 | public function accept(ArmyVisitor $visitor) { 96 | $method = "visit" . get_class($this); 97 | $visitor->$method($this); 98 | } 99 | 100 | protected function setDepth($depth) { 101 | $this->depth=$depth; 102 | } 103 | 104 | public function getDepth() { 105 | return $this->depth; 106 | } 107 | } 108 | 109 | abstract class CompositeUnit extends Unit { 110 | private $units = array(); 111 | 112 | public function getComposite() { 113 | return $this; 114 | } 115 | 116 | protected function units() { 117 | return $this->units; 118 | } 119 | 120 | public function addUnit(Unit $unit) { 121 | if (in_Array($unit, $this->units, true)) { 122 | return; 123 | } 124 | 125 | $unit->setDepth($this->getDepth() + 1); 126 | $this->units[] = $unit; 127 | } 128 | 129 | public function removeUnit(Unit $unit) { 130 | //$this->units = array_udiff($this->units, array($unit), function($a, $b){ return ($a === $b)?0:1; }); //PHP 5.3寫法 131 | $this->units = array_udiff($this->units, array($unit), create_function('$a, $b', 'return ($a === $b)?0:1;')); 132 | } 133 | 134 | public function accept(ArmyVisitor $visitor) { 135 | parent::accept($visitor); 136 | foreach($this->units as $thisunit){ 137 | $thisunit->accept($visitor); 138 | } 139 | } 140 | } 141 | 142 | 143 | 144 | 145 | class Army extends CompositeUnit 146 | { 147 | public function bombardStrength(){ 148 | $ret = 0; 149 | foreach ($this->units() as $unit) { 150 | $ret += $unit->bombardStrength(); 151 | } 152 | return $ret; 153 | } 154 | } 155 | 156 | class TroopCarrier extends CompositeUnit 157 | { 158 | public function addUnit(Unit $unit) { // 將單位加入 159 | 160 | if ($unit instanceof Cavalry) { 161 | throw new Exception("Can't get a horse on the vehicle"); 162 | } 163 | parent::addUnit($unit); 164 | } 165 | 166 | public function bombardStrength() { // 計算總攻擊力 167 | return 0; 168 | } 169 | } 170 | 171 | 172 | // 弓箭手 173 | class Archer extends Unit { 174 | public function bombardStrength() { 175 | return 4; 176 | } 177 | } 178 | 179 | // 雷射加農砲 180 | class LaserCannonUnit extends Unit { 181 | public function bombardStrength() { 182 | return 44; 183 | } 184 | } 185 | 186 | // 騎兵 187 | class Cavalry extends Unit { 188 | public function bombardStrength() { 189 | return 15; 190 | } 191 | } 192 | 193 | 194 | 195 | 196 | 197 | ?> -------------------------------------------------------------------------------- /example/trunk/public/example/abstractClassAndInterface.php: -------------------------------------------------------------------------------- 1 | addItem($pet); 13 | $insurableReader->addItem($human); 14 | //$insurableReader->addItem($shark); // Shark沒有定義Insurable這個interface,故發生錯誤 15 | $insurableReader->addItem($house); 16 | $insurableReader->printItems(); 17 | 18 | 19 | echo '
'; 20 | 21 | $animalReader = new AnimalReader(); // Animal讀起器 22 | 23 | $animalReader->addItem($pet); 24 | $animalReader->addItem($human); 25 | $animalReader->addItem($shark); 26 | //$animalReader->addItem($house); // House沒有繼承至Animal這個abstract class,故發生錯誤 27 | $animalReader->printItems(); 28 | ?> 29 | -------------------------------------------------------------------------------- /example/trunk/public/example/couplingAndCohesion.php: -------------------------------------------------------------------------------- 1 | addItem($circle1); 10 | $lister->addItem($square1); 11 | $lister->out(); 12 | ?> -------------------------------------------------------------------------------- /example/trunk/public/example/polymorphism.php: -------------------------------------------------------------------------------- 1 | draw($circle); 13 | $shape->draw($rectangle); 14 | */ 15 | 16 | /* 17 | $circle = new Circle(); 18 | $rectangle = new Rectangle(); 19 | */ 20 | 21 | // $shape = new Shape(); 22 | $circle = new Circle(); 23 | $rectangle = new Rectangle(); 24 | $drawer = new Drawer(); 25 | 26 | $drawer->addShape($circle); 27 | $drawer->addShape($rectangle); 28 | 29 | $drawer->drawAllShapes(); 30 | 31 | // $shapInterface = new ShapeInterface(); 32 | ?> 33 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hank7444/DesignPatternPHP/27a53e69facb12bf7249ce98793e87fa49a079c6/example/trunk/public/pattern/.DS_Store -------------------------------------------------------------------------------- /example/trunk/public/pattern/abstractFactory.php: -------------------------------------------------------------------------------- 1 | outputTerranUnit(); //產生人類士兵 7 | $zergUnit = $barrack->outputZergUnit(); //產生異形士兵 8 | 9 | $terranUnit->playSlogan(); 10 | $zergUnit->shout(); 11 | 12 | 13 | $commandCenter = new CommandCenter(); //建立指揮中心 14 | $terranUnit = $commandCenter->outputTerranUnit(); //產生人類工兵 15 | $zergUnit = $commandCenter->outputZergUnit(); //產生異形工兵 16 | 17 | $terranUnit->playSlogan(); 18 | $zergUnit->shout(); 19 | 20 | 21 | $airport = new Airport(); //建立機場 22 | $terranUnit = $airport->outputTerranUnit(); //產生人類飛機 23 | $zergUnit = $airport->outputZergUnit(); //產生異形飛機 24 | 25 | $terranUnit->playSlogan(); 26 | $zergUnit->shout(); 27 | 28 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/adapter.php: -------------------------------------------------------------------------------- 1 | usb_connect(); 11 | $ps2UsbAdapter->usb_click(); 12 | $ps2UsbAdapter->usb_move(); 13 | 14 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/bridge.php: -------------------------------------------------------------------------------- 1 | play(); 11 | 12 | 13 | $angryBirdSpaceIOS = new AngryBirdSpace($iosPlatform); 14 | $angryBirdSpaceIOS->play(); 15 | 16 | ?> 17 | 18 | 19 | play(); 24 | 25 | echo '
'; 26 | 27 | $iosAngryBirdSpace = new iosAngryBirdSpace(); 28 | echo $iosAngryBirdSpace->play(); 29 | */ 30 | 31 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/builder.php: -------------------------------------------------------------------------------- 1 | setMealBuilder($chickenKitMealBuilder); 10 | $chickenKitMeal = $mealDirector->buildMeal(); 11 | $chickenKitMeal->showMeal(); 12 | 13 | $mealDirector->setMealBuilder($beefKitMealBuilder); 14 | $beefKitMeal = $mealDirector->buildMeal(); 15 | $beefKitMeal->showMeal(); 16 | 17 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/chainOfResponsibility.php: -------------------------------------------------------------------------------- 1 | setSuccessor($cacheLogger); 11 | $dbLogger->setSuccessor($sessionLogger); 12 | 13 | $msg = $dbLogger->handleRequest($data); // 順序為 dbLogger -> sessionLogger -> cacheLogger 14 | 15 | echo $msg; // cache log寫入 16 | exit; 17 | 18 | 19 | 20 | 21 | $chineseDirtyWordHandler = new ChineseDirtyWordFilter(); // 中文髒話過濾 22 | $englishDirtyWordHandler = new EnglishDirtyWordFilter(); // 英文髒話過濾 23 | 24 | $msg = "你這個人真三八,是一個idiot,講的話都是bullshit,真像一個笨蛋加白癡,王八蛋!!"; 25 | 26 | //$msg = $chineseDirtyWordHandler->handleRequest($msg); 27 | //echo $msg; // 你這個人真***,是一個idiot,講的話都是bullshit,真像一個***加***,***!! 28 | 29 | //$msg = $englishDirtyWordHandler->handleRequest($msg); 30 | //echo $msg; // 你這個人真三八,是一個???,講的話都是bull???,真像一個笨蛋加白癡,王八蛋!! 31 | 32 | $chineseDirtyWordHandler->setSuccessor($englishDirtyWordHandler); // 設定承接response的下家 33 | 34 | $msg = $chineseDirtyWordHandler->handleRequest($msg); 35 | echo $msg; // 你這個人真***,是一個???,講的話都是???,真像一個***加***,***!! 36 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/command.php: -------------------------------------------------------------------------------- 1 | setCommand(0, $carPowerOn); // 將按鈕0號設為發動汽車引擎 14 | $remoteControl->setCommand(1, $carPowerOff); // 將按鈕1號設為關閉汽車引擎 15 | $remoteControl->setCommand(2, $carTurnLeft); // 將按鈕2號設為汽車左轉 16 | $remoteControl->setCommand(3, $carTurnRight); // 將按鈕3號設為汽車右轉 17 | 18 | /* 19 | $remoteControl->execute(0); // 按下按鈕0號 20 | $remoteControl->execute(1); // 按下按鈕1號 21 | $remoteControl->execute(2); // 按下按鈕2號 22 | $remoteControl->execute(3); // 按下按鈕3號 23 | */ 24 | 25 | // 設定蛇行巨集, 開啟引擎、左轉、右轉、關閉引擎 26 | $macroCmd = new MarcoCommand(array($carPowerOn, $carTurnLeft, $carTurnRight, $carPowerOff)); 27 | 28 | // 將按鈕4號設為蛇行指令 29 | $remoteControl->setCommand(4, $macroCmd); 30 | 31 | // 執行按鈕4號 32 | $remoteControl->execute(4); 33 | 34 | 35 | 36 | /* 37 | $boat = new Boat(); 38 | $boatPowerOn = new PowerOnCommand($boat); 39 | $boatPowerOff = new PowerOffCommand($boat); 40 | 41 | 42 | $remoteControl->setCommand(2, $boatPowerOn); //將按鈕2號設為發動汽船引擎 43 | $remoteControl->setCommand(3, $boatPowerOff); //將按鈕3號設為關閉汽船引擎 44 | */ 45 | 46 | 47 | 48 | 49 | 50 | 51 | ?> 52 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/commandUndo.php: -------------------------------------------------------------------------------- 1 | execute($dummyWordPaste, ",哇哈哈"); // 今天天氣真好,哇哈哈 12 | $controlManager->execute($dummyWordPaste, ",你好嗎"); // 今天天氣真好,哇哈哈,你好嗎 13 | 14 | $controlManager->undo(); // 今天天氣真好,哇哈哈 15 | $controlManager->undo(); // 今天天氣真好 16 | $controlManager->redo(); // 今天天氣真好,哇哈哈 17 | $controlManager->redo(); // 今天天氣真好,哇哈哈,你好嗎 18 | 19 | echo "
"; 20 | 21 | $controlManager->execute($dummyWordCut, "今天"); // 天氣真好,哇哈哈,你好嗎 22 | 23 | // 三次undo 24 | $controlManager->undo(); // 今天天氣真好,哇哈哈,你好嗎 25 | $controlManager->undo(); // 今天天氣真好,哇哈哈 26 | $controlManager->undo(); // 今天天氣真好 27 | 28 | 29 | // 到第四次undo已經沒有資料了,所以沒有任何字串出現 30 | $controlManager->undo(); 31 | 32 | 33 | // 三次redo 34 | $controlManager->redo(); // 今天天氣真好,哇哈哈 35 | $controlManager->redo(); // 今天天氣真好,哇哈哈,你好嗎 36 | $controlManager->redo(); // 天氣真好,哇哈哈,你好嗎 37 | 38 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/composite.php: -------------------------------------------------------------------------------- 1 | bombardStrength()}" . "
"; 7 | 8 | 9 | $main_army = new Army(); 10 | 11 | $main_army->addUnit($archer); 12 | $main_army->addUnit(new Archer()); 13 | $main_army->addUnit(new LaserCannonUnit()); 14 | 15 | echo "main_army attacking with strength: {$main_army->bombardStrength()}" . "
"; 16 | 17 | $sub_army = new Army(); 18 | 19 | $sub_army->addUnit(new Archer()); 20 | $sub_army->addUnit(new Cavalry()); 21 | $sub_army->addUnit(new Cavalry()); 22 | echo "sub_army attacking with strength: {$sub_army->bombardStrength()}" . "
"; 23 | 24 | 25 | 26 | $main_army->addUnit($sub_army); 27 | 28 | echo "main_army attacking with strength: {$main_army->bombardStrength()}" . "
"; 29 | 30 | $troop = new TroopCarrier(); 31 | 32 | //$troop->addUnit(new Cavalry); 33 | $troop->addUnit(new Archer()); 34 | $troop->addUnit(new Archer()); 35 | //$troop->addUnit(new Cavalry()); 36 | 37 | echo "troop attacking with strength: {$troop->bombardStrength()}" . "
"; 38 | 39 | 40 | $main_army->addUnit($troop); 41 | 42 | echo "attacking with strength: {$main_army->bombardStrength()}" . "
"; 43 | ?> 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/decorator.php: -------------------------------------------------------------------------------- 1 | getWealthFactor() . "
"; 8 | 9 | $tile = new DiamondDecorator(new Plains()); // 平原+鑽石資源 10 | 11 | echo $tile->getWealthFactor() . "
"; 12 | 13 | $tile = new PollutionDecorator(new DiamondDecorator(new Plains())); // 平原+鑽石資源+汙染 14 | 15 | echo $tile->getWealthFactor() . "
"; 16 | 17 | 18 | //$process = new AuthenticateRequest(new StructureRequest( new LogRequest( new MainProcess()))); 19 | //$process->process(new RequestHelper()); 20 | 21 | ?> 22 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/facade.php: -------------------------------------------------------------------------------- 1 | add(254, 113) . "
"; 7 | $divider = new Divider(); 8 | echo "256 / 8 = " . $divider->divide(256, 8) . "
"; 9 | 10 | 11 | $calculatorFacade = new CalculatorFacade(); 12 | echo "254 + 113 = " . $calculatorFacade->calculate("254 + 113") . "
"; 13 | echo "256 / 8 = " . $calculatorFacade->calculate("256 / 8") . "
"; 14 | */ 15 | 16 | 17 | $amplifier = new Amplifier("Top-O-Line Amplifier"); 18 | $tuner = new Tuner($amplifier, "Top-O-Line AM/FM Tuner"); 19 | $dvd = new DVDPlayer("Top-O-Line DVD Player", $amplifier); 20 | $cd = new CDPlayer($amplifier, "Top-O-Line CD Player"); 21 | $projector = new Projector("Top-O-Line Projector", $dvd); 22 | $lights = new TheaterLights("Theater Ceiling Lights"); 23 | $screen = new Screen("Theater Screen"); 24 | $movie = 'TopGun'; 25 | 26 | 27 | $homeTheater = new HomeTheaterFacade($amplifier, $tuner, $dvd, $cd, $projector, $screen, $lights); 28 | $homeTheater->watchMovie($movie); 29 | 30 | 31 | /* 32 | echo "Get ready to watch a movie...
"; 33 | $lights->on(); 34 | $lights->dim(10); 35 | $screen->down(); 36 | $projector->on(); 37 | $projector->wideScreenMode(); 38 | $amplifier->on(); 39 | $amplifier->setDVD($dvd); 40 | $amplifier->setSurroundSound(); 41 | $amplifier->setVolume(5); 42 | $dvd->on(); 43 | $dvd->play($movie); 44 | */ 45 | 46 | /* 47 | echo "Get ready to watch a movie...
"; 48 | $lights->on(); 49 | $lights->dim(10); 50 | $screen->down(); 51 | $projector->on(); 52 | $projector->wideScreenMode(); 53 | $amplifier->on(); 54 | $amplifier->setDVD($dvd); 55 | $amplifier->setSurroundSound(); 56 | $amplifier->setVolume(5); 57 | $dvd->on(); 58 | $dvd->play($movie); 59 | */ 60 | 61 | 62 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/factory.php: -------------------------------------------------------------------------------- 1 | outputUnit(); // 產生單位 7 | $solider->playSlogan(); 8 | 9 | 10 | $commandCenter = new CommandCenter(); // 建立指揮中心 11 | $worker = $commandCenter->outputUnit(); // 產生單位 12 | $worker->playSlogan(); 13 | 14 | 15 | $airport = new Airport(); // 建立機場 16 | $aircraft = $airport->outputUnit(); // 產生單位 17 | $aircraft->playSlogan(); 18 | 19 | 20 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/flyweight.php: -------------------------------------------------------------------------------- 1 | "; 19 | 20 | for ($i = 0; $i < 100000; $i++) { 21 | 22 | $char = $charArr[rand(0, 25)]; 23 | $size = $sizeArr[rand(0, 10)]; 24 | $color = $colorArr[rand(0, 7)]; 25 | $posX = rand(0, 1000); 26 | $posY = rand(0, 1000); 27 | 28 | $character = new Character($char, $size, $color, $posX, $posY); 29 | $chars[] = $character; 30 | 31 | } 32 | 33 | 34 | // 取得記憶體使用量 35 | $MaxMem = memory_get_peak_usage(); 36 | $MEM = memory_get_usage() - $MEMBefore; 37 | 38 | echo "產生物件後記憶體目前用掉{$MEM} , 最多用掉{$MaxMem} "; 39 | 40 | 41 | 42 | 43 | /* 44 | //$character = $flyweightFactory->getFlyweight($char); 45 | //$character->showChar($size, $color, $posX, $posY); 46 | 47 | $charsExtrinasicStatus[] = array($char, $size, $color, $posX, $posY); 48 | */ 49 | 50 | /* 51 | // Displays the amount of memory being used as soon as the script runs 52 | echo memory_get_usage() . "
"; // Returns 46552 Bytes 53 | 54 | //Your code goes here 55 | $a = str_repeat('Avinash Pawar', 100000); 56 | 57 | // Displays the amount of memory being used by your code 58 | echo memory_get_usage() . "
"; // Returns 176636 Bytes 59 | */ 60 | 61 | 62 | /* 63 | // unshared 64 | $uflyweight = $flyweightFactory->getFlyweight(array('state A', 'state B')); 65 | $uflyweight->operation('other state A'); 66 | 67 | 68 | 69 | $flyweightFactory = new FlyweightFactory(); 70 | $flyweight = $flyweightFactory->getFlyweight("state A"); 71 | $flyweight->operation("other state A"); 72 | 73 | $flyweight = $flyweightFactory->getFlyweight("state B"); 74 | $flyweight->operation("other state B"); 75 | 76 | echo "
"; 77 | 78 | 79 | // unshared 80 | $uflyweight = $flyweightFactory->getFlyweight(array('state A', 'state B')); 81 | $uflyweight->operation('other state A'); 82 | */ 83 | ?> 84 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/interpreter.php: -------------------------------------------------------------------------------- 1 | build($statement); 9 | $result = $calculator->compute(); 10 | 11 | echo "計算結果:" . $result; 12 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/iterator.php: -------------------------------------------------------------------------------- 1 | addUnit($archer); 10 | $main_army->addUnit(new Archer()); 11 | $main_army->addUnit(new LaserCannonUnit()); 12 | 13 | 14 | $sub_army = new Army(); 15 | 16 | $sub_army->addUnit(new Archer()); 17 | $sub_army->addUnit(new Cavalry()); 18 | $sub_army->addUnit(new Cavalry()); 19 | 20 | 21 | $main_army->addUnit($sub_army); 22 | 23 | 24 | 25 | $compositeIterator = $main_army->createIterator(); 26 | 27 | //$unit = $compositeIterator->current(); 28 | //echo $unit->getName(); 29 | 30 | $unit = $compositeIterator->next(); 31 | echo $unit->getName(); 32 | 33 | $unit = $compositeIterator->next(); 34 | echo $unit->getName(); 35 | 36 | $unit = $compositeIterator->next(); 37 | echo $unit->getName(); 38 | 39 | $unit = $compositeIterator->next(); 40 | echo $unit->getName(); 41 | 42 | $compositeIterator->next(); 43 | $compositeIterator->next(); 44 | 45 | echo "
"; 46 | 47 | 48 | $subCompositeIterator = $unit->createIterator(); 49 | 50 | $unit = $subCompositeIterator->next(); 51 | echo $unit->getName(); 52 | 53 | $unit = $subCompositeIterator->next(); 54 | echo $unit->getName(); 55 | 56 | $unit = $subCompositeIterator->next(); 57 | echo $unit->getName(); 58 | 59 | $subCompositeIterator->next(); 60 | 61 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/mediator.php: -------------------------------------------------------------------------------- 1 | setMediator($formMediator); 21 | $clearBtn->setMediator($formMediator); 22 | $parentList->setMediator($formMediator); 23 | $childList->setMediator($formMediator); 24 | 25 | $copyBtn->execute(); // 複製按鈕目前禁用中 26 | $clearBtn->execute(); // 清除按鈕目前禁用中 27 | 28 | $parentList->setData($data); 29 | $parentList->select("台北市"); // 母項目選擇了台北市,以下是子項目列表: 30 | // Array ( [0] => 內湖區 [1] => 大安區 [2] => 中正區 [3] => 中山區 ) 31 | $copyBtn->execute(); // 複製按鈕按下 32 | $clearBtn->execute(); // 清除按鈕目前禁用中 33 | 34 | $childList->select("內湖區"); // 子項目選擇了內湖區 35 | $copyBtn->execute(); // 複製按鈕按下 36 | $clearBtn->execute(); // 清除按鈕按下,已將子列表的內容清除! 37 | 38 | $copyBtn->execute(); // 複製按鈕目前禁用中 39 | $clearBtn->execute(); // 清除按鈕目前禁用中 40 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/memento.php: -------------------------------------------------------------------------------- 1 | showState(); 8 | 9 | $backup = new Role(0, 0, 0, 0, 0); 10 | $backup->setState($jack->getHp(), $jack->getMp(), // 備份目前狀態, 11 | $jack->getDex(), $jack->getAtk(), // 但是這邊暴露了實作細節 12 | $jack->getDef()); 13 | 14 | $jack->fight(); // 開打,死掉了 15 | $jack->showState(); 16 | 17 | $jack->setState($backup->getHp(), $backup->getMp(), // 回復之前狀態 18 | $backup->getDex(), $backup->getAtk(), 19 | $backup->getDef()); 20 | 21 | $jack->showState(); 22 | */ 23 | 24 | // 使用Memento範例 25 | $jack = new Role(100, 30, 60, 40, 35); // 建立遊戲角色 26 | $jack->showState(); 27 | 28 | $caretaker = new Caretaker(); 29 | 30 | $caretaker->setMemento($jack->saveState()); // 備份目前狀態 31 | 32 | $jack->fight(); // 開打,死掉了 33 | $jack->showState(); 34 | 35 | $jack->recoveryState($caretaker->getMemento()); // 回復之前狀態 36 | $jack->showState(); 37 | 38 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/observer.php: -------------------------------------------------------------------------------- 1 | attach(new SecurityMonitor()); // 將安全監控類別註冊 7 | $login->handleLogin("", "hank", "192.168.1.101"); 8 | */ 9 | 10 | 11 | $login = new Login(); 12 | new SecurityMonitor($login); 13 | new GeneralLogger($login); 14 | new PartnershipTool($login); 15 | $login->handleLogin("", "hank", "192.168.1.101"); 16 | 17 | ?> 18 | -------------------------------------------------------------------------------- /example/trunk/public/pattern/prototype.php: -------------------------------------------------------------------------------- 1 | show(); 11 | print_r($novel1); 12 | 13 | echo "

"; 14 | 15 | // 複製$novel; 16 | $novel2 = clone $novel1; 17 | $novel2->show(); 18 | print_r($novel2); 19 | 20 | // 修改novel2的title 21 | $novel2->setTitle('modified Novel2 Title'); 22 | 23 | echo "

"; 24 | $novel1->show(); 25 | 26 | echo "

"; 27 | $novel2->show(); 28 | 29 | echo "

"; 30 | $novel3 = $novel2; 31 | $novel3->show(); 32 | print_r($novel3); 33 | 34 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/proxy.php: -------------------------------------------------------------------------------- 1 | modifyUserInfo(); 8 | $permissionProxy->viewNote(); 9 | $permissionProxy->publishNote(); 10 | $permissionProxy->modifyNote(); 11 | 12 | echo "
"; 13 | $permissionProxy->setLevel(1); 14 | $permissionProxy->modifyUserInfo(); 15 | $permissionProxy->viewNote(); 16 | $permissionProxy->publishNote(); 17 | $permissionProxy->modifyNote(); 18 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/simpleFactory.php: -------------------------------------------------------------------------------- 1 | outputUnit('solider'); // 建立士兵 8 | $worker = $building->outputUnit('worker'); // 建立工兵 9 | 10 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/singleton.php: -------------------------------------------------------------------------------- 1 | setProperty("name", "matt"); 9 | 10 | unset($pref); 11 | 12 | $pref2 = Preferences::getInstance(); 13 | echo $pref2->getProperty("name"); 14 | 15 | 16 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/state.php: -------------------------------------------------------------------------------- 1 | '; 8 | 9 | $candyMachine->insertCoin(); 10 | $candyMachine->insertCoin(); 11 | $candyMachine->ejectCoin(); 12 | $candyMachine->ejectCoin(); 13 | $candyMachine->turnCrank(); 14 | $candyMachine->dispense(); 15 | 16 | echo '
'; 17 | 18 | $candyMachine->insertCoin(); 19 | $candyMachine->turnCrank(); 20 | $candyMachine->dispense(); 21 | 22 | echo '
'; 23 | 24 | $candyMachine->turnCrank(); 25 | $candyMachine->dispense(); 26 | 27 | echo '
'; 28 | 29 | $candyMachine->insertCoin(); 30 | $candyMachine->turnCrank(); 31 | $candyMachine->ejectCoin(); 32 | $candyMachine->dispense(); 33 | 34 | 35 | echo '
'; 36 | $candyMachine->insertCoin(); 37 | $candyMachine->turnCrank(); 38 | $candyMachine->dispense(); 39 | $candyMachine->ejectCoin(); 40 | 41 | 42 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/strategy.php: -------------------------------------------------------------------------------- 1 | useStrategy(); 7 | 8 | echo '
'; 9 | 10 | $officer->setStractegy(new ScoffStrategy()); 11 | echo $officer->useStrategy(); 12 | 13 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/templateMethod.php: -------------------------------------------------------------------------------- 1 | readFileProcess(); 9 | 10 | echo "
"; 11 | 12 | $adobeTextReader->readFileProcess(); 13 | 14 | ?> -------------------------------------------------------------------------------- /example/trunk/public/pattern/visitor.php: -------------------------------------------------------------------------------- 1 | accept($textdump); 9 | echo $textdump->getText(); 10 | 11 | echo "
"; 12 | 13 | $main_army = new Army(); 14 | $main_army->addUnit(new Archer()); 15 | $main_army->addUnit(new LaserCannonUnit()); 16 | $main_army->addUnit(new Cavalry()); 17 | 18 | $sub_army = new Army(); 19 | $sub_army->addUnit(new Archer()); 20 | $sub_army->addUnit(new Archer()); 21 | $sub_army->addUnit(new Archer()); 22 | 23 | $main_army->addUnit($sub_army); 24 | $main_army->accept($textdump); 25 | echo $textdump->getText(); 26 | 27 | echo "
"; 28 | 29 | //列出每個單位要繳的稅金 30 | $taxcollector = new TaxCollectionVisitor(); 31 | 32 | $archer->accept($taxcollector); 33 | echo $taxcollector->getReport(); 34 | 35 | echo "
"; 36 | 37 | $main_army->accept($taxcollector); 38 | echo $taxcollector->getReport(); 39 | 40 | 41 | echo "
"; 42 | 43 | //列出總和 44 | echo "total:" . $taxcollector->getTax(); 45 | 46 | 47 | /* 48 | $troop = new TroopCarrier(); 49 | 50 | //$troop->addUnit(new Cavalry); 51 | $troop->addUnit(new Archer()); 52 | $troop->addUnit(new Archer()); 53 | //$troop->addUnit(new Cavalry()); 54 | 55 | $main_army->addUnit($troop); 56 | 57 | echo "attacking with strength: {$main_army->bombardStrength()}"; 58 | */ 59 | 60 | ?> 61 | -------------------------------------------------------------------------------- /slide.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hank7444/DesignPatternPHP/27a53e69facb12bf7249ce98793e87fa49a079c6/slide.ppt --------------------------------------------------------------------------------