設計モードの観察者モード&&状態モード

9854 ワード

<?php



interface Subject {

	function attach($obj);

	function detach($name);

	function notify();

}



class Teacher implements Subject {

	private $attachArr = array();



	function __construct() {

	}



	function attach($obj) {

    	array_push($this->attachArr, $obj);

	}



	function detach($name) {

		unset($name);

	}



	function notify() {

		foreach($this->attachArr as $obj) {

			$obj->work();

		}

	}



	function setStatus($status) {

		$this->status = $status;

	}





}
 

interface Observe {     function work(); }
class Student implements Observe {



	function __construct($name, $work, $subjectObj) {

		$this->name = $name;

		$this->subjectObj = $subjectObj;

		$this->work = $work;

	}



	function work() {

		echo $this->subjectObj->status . "
" .$this->name . $this->work . "
"; } } $teacher = new Teacher(); $student1 = new Student('joey', 'paly table tenice', $teacher); $student2 = new Student('jam', 'sleeping', $teacher); $teacher->attach($student1); $teacher->attach($student2); $teacher->setStatus("quitting time
"); $teacher->notify();

 
以上のコードはオブザーバーモード
オブザーバモードは、1つのオブジェクトの状態が変化すると、他の関連オブジェクトも対応します.
オブザーバモードの欠点:各オブザーバオブジェクトはこの抽出されたインタフェースクラス(ここのワークなど)を継承しなければならず、いくつかの不便をもたらします.
依頼で実現できます.
 
<?php

//    



abstract class State {

	abstract  function writeProgram(Work $work);

}



class ForenoonState extends State {

	function writeProgram(Work $work) {

	  if ($work->hour < 12) {

	     echo '       ' . $work->hour . '       ';

	  } else {

	     $work->setState(new NoonState());

		 $work->writeProgram();

	  }



	}

}



class NoonState extends State {

    function writeProgram(Work $work) {

	    if ($work->hour < 13 && $work->hour >= 12) {

		   echo '     ' . $work->hour . '       ';

		} else {

		   $work->setState( new AfternoonState());

		   $work->writeProgram();

		}

	}

}



class AfternoonState extends State {

    function writeProgram(Work $work) {

		if ($work->hour > 13 && $work->hour < 17) {

		   echo '     ' . $work->hour . '        ';

		} else {

		   $work->setState(new EveningState());

		   $work->writeProgram();

		}

	}

}



class EveningState extends State {

    function writeProgram(Work $work) {

	    if ($work->finish) {

			$work->setState(new RestState());

			$work->writeProgram();

		} else {

		    if ($work->hour < 21) {

               echo '     ' . $work->hour . '     ';

			}

		}

	}

}



class RestState extends State {

    function writeProgram(Work $work) {

	    echo '     ' . $work->hour . '     ';

	}

}



class Work {

    private $state;

	public  $hour;

	public  $finish = false; 

	function __construct() {

	    $this->state = new ForenoonState();

	}



	function setState($state) {

		$this->state = $state;

	}



	function taskFinished() {

		$this->finish = true;

	}

	function writeProgram() {

		$this->state->writeProgram($this);

	}

}



$task = new Work();

$task->hour = 8;

$task->writeProgram();

$task->hour = 12;

$task->writeProgram();



$task->hour = 15;

$task->writeProgram();

$task->hour = 20;

$task->taskFinished();

$task->writeProgram();

ステータスモードは、判断ロジックが長すぎる場合に、新しいステータスが追加された場合に元のステータスを変更しないコードに適応します.