Review PHP设计模式之——观测模式
观测模式:
1 <?php 2 class car implements SplSubject{ 3 private $carName; //车的类型 4 private $carState=0; //车的状态,0为关闭,1这启动车子 5 private $carSpeed=0; //初始化车的速度表值 6 private $Observers; //各项车的性能观察对象 7 8 public function __construct($Name){ 9 $this->carName=$Name; 10 $this->Observers=new SplObjectStorage; 11 } 12 13 //启动 14 public function start(){ 15 $this->carState=1; 16 $this->notify(); 17 } 18 19 //停车 20 public function stop(){ 21 $this->carState=0; 22 $this->carSpeed=0; 23 $this->notify(); 24 } 25 26 //加速 27 public function accelerate($Acceleration){ 28 if(0===$this->carState){ 29 throw new Exception('Please start!'); 30 } 31 if(!is_int($Acceleration) || $Acceleration<0){ 32 throw new Exception('The value of acceleration is invalid!'); 33 } 34 $this->carSpeed+=$Acceleration; 35 $this->notify(); 36 } 37 38 //增加监测对象 39 public function attach(SplObserver $observer){ 40 if(!$this->Observers->contains($observer)){ 41 $this->Observers->attach($observer); 42 } 43 return true; 44 } 45 46 //删除监测对象 47 public function detach(SplObserver $observer){ 48 if(!$this->Observers->contains($observer)){ 49 return false; 50 } 51 $this->Observers->detach($observer); 52 return true; 53 } 54 55 //传送对象 56 public function notify(){ 57 foreach($this->Observers as $observer){ 58 $observer->update($this); 59 } 60 } 61 62 public function __get($Prop){ 63 switch($Prop){ 64 case 'STATE': 65 return $this->carState; 66 break; 67 case 'SPEED': 68 return $this->carSpeed; 69 break; 70 case 'NAME': 71 return $this->carName; 72 break; 73 default: 74 throw new Exception($Prop.'can not be read'); 75 } 76 } 77 78 public function __set($Prop,$Val){ 79 throw new Exception($Prop.'can not be set'); 80 } 81 } 82 83 class carStateObserver implements SplObserver{ 84 private $SubjectState; 85 public function update(SplSubject $subject){ 86 switch($subject->STATE){ 87 case 0: 88 if(is_null($this->SubjectState)){ 89 echo $subject->NAME.' not started'."\n"; 90 }else{ 91 echo $subject->NAME.' stalling of engine'."\n"; 92 } 93 $this->SubjectState=0; 94 break; 95 case 1: 96 if(1!==$this->SubjectState){ 97 echo $subject->NAME.' is starting'."\n"; 98 $this->SubjectState=1; 99 } 100 break; 101 default: 102 throw new Exception('Unexpected error in carStateObserver::update()'); 103 } 104 } 105 } 106 107 class carSpeedObserver implements SplObserver{ 108 public function update(SplSubject $subject){ 109 if(0!==$subject->STATE){ 110 echo $subject->NAME.' current speed is '.$subject->SPEED.'Kmh'."\n"; 111 } 112 } 113 } 114 115 class carOverspeedObserver implements SplObserver{ 116 public function update(SplSubject $subject){ 117 if($subject->SPEED>130){ 118 throw new Exception('The max speed is 130, you are breaking up!'."\n"); 119 } 120 } 121 } 122 123 try{ 124 $driver = new car('AUDIA4'); 125 $driver->attach(new carStateObserver); 126 $driver->attach(new carSpeedObserver); 127 $driver->attach(new carOverspeedObserver); 128 $driver->start(); 129 $driver->accelerate(10); 130 $driver->accelerate(30); 131 $driver->stop(); 132 $driver->start(); 133 $driver->accelerate(50); 134 $driver->accelerate(70); 135 $driver->accelerate(100); 136 $driver->accelerate(150); 137 } 138 catch(Exception$e){ 139 echo $e->getMessage(); 140 } 141 ?>