言語の文法
<Job> ::= begin <CommandList> <CommandList> ::= <Command>* end <Command> ::= diskspace | date | line
interface Command { public function execute(Context $context); }
JobCommand.php
<Job> ::= begin <CommandList>
class JobCommand implements Command { public function execute(Context $context) { if($context->getCurrentCommand() !== 'begin') { throw new RuntimeException(); } $commandList = new CommandListCommand(); $commandList->execute($context->next); } }
CommandListCommand.php
<CommandList> ::= <Command>* end
class CommandListCommand implements Command { public function execute(Context $context) { while(true) { $currentCommand = $context->getCurrentCommand(); if(is_null($currentCommand)) { throw new RuntimeException(); } else if($currentCommand === 'end') { break; } else { $command = new CommandCommand(); $command->execute($context); } } $context->next(); } }
CommandCommand.php
<Command> ::= diskspace | date | line
class CommandCommand implements Command { public function execute(Context $context) { $currentCommand = $context->getCurrentCommand(); if($currentCommand === 'diskspace') { // 空き容量を計算して出力 } else if($currentCommand === 'date') { // 日付出力 } else if($currentCommand === 'line') { // 罫線を出力 } else { new RuntimeException(); } } }
Context.php
class Context { private $commands; private $currentIndex = 0; private $maxIndex = 0; public function __construct($command) { $this->commands = split(' +', trim($command)); $this->maxIndex = count($this->commands); } public function next() { $this->currentIndex++; return $this; } public function getCurrentCommand() { if(!array_key_exists($this->currentIndex, $this->commands)) { return null; } return trim($this->commands[$this->currentIndex]); } }
3>■クライアントコード
$job = new JobCommand(); $job->execute(new Context('begin date line diskspace end'));