Systemblockdiagramm:
Es gibt vier Hauptbefehlsverteilungscontroller Aufgabe:
1. Systeminitialisierung, Systemkonfigurationsparameter laden und diese Daten zwischenspeichern. Diese Konfigurationsparameter auf Anwendungsebene können den Serialisierungsmechanismus verwenden, um die Daten zwischenzuspeichern, ohne die Datei jedes Mal lesen zu müssen, wodurch die Zugriffseffizienz beschleunigt wird.
2. Sammeln Sie basierend auf der Front-End-Anfrage Parameter, um eine Anfrage (Request) zu generieren.
3. Ordnen Sie die Anfrage dem Befehlsmodul (Command) einer bestimmten Geschäftslogik zu.
4. Führen Sie den Vorgang aus und geben Sie das Ergebnis an die Front-End-Ansicht zurück.
Die Geschäftslogikschicht kann Ausführungsparameter basierend auf dem eingehenden Kontextobjekt erhalten. Nach der Ausführung kann das Ausführungsergebnis über das Kontextobjekt an die vorherige Schicht zurückgegeben werden.
Implementierung des Befehlsverteilungscontrollers:
class Controller{ private function __construct() {} static function run(){ $instance = new Controller(); $instance->init(); $instance->handleRequest(); } function init(){ $application = \base\ApplicationHelper::instance(); $application->system_init(); } function handleRequest(){ $request = new \controller\Request(); $cmd_r = new \command\CommandResolver(); $cmd = $cmd_r->get_command($request); $cmd->execute($request); } }
Für interpretierte Sprachen wie PHP muss zur Implementierung des Undeo/Redo-Mechanismus ein Caching-Mechanismus (Sitzung) verwendet werden, um den Verlauf der Befehlsausführung zu speichern. Das Sitzungsmodul hier ist hauptsächlich für die Verwaltung eines Befehlsverlaufsdatensatzes verantwortlich und seine Implementierung ist wie folgt:
namespace base; require_once('session_registry.php'); class SessionMementoTaker extends SessionRegistry{ const COMMAND_COUNT = 5; private $persent = 0; private $cmd_stack = array(); static public function instance(){ return parent::instance(); } public function push_command(Command $cmd){ $this->cmd_stack = self::instance()->get('cmd_stack'); if(!empty($this->cmd_stack)){ if(count($this->cmd_stack) >self::COMMAND_COUNT){ array_shift($this->cmd_stack); reset($this->cmd_stack); } } array_push($this->cmd_stack, $cmd); $this->persent = count($this->cmd_stack) + 1; self::instance()->set('cmd_stack', $this->cmd_stack); self::instance()->set('cmd_persent', $this->persent); } public function get_undo_command(){ $this->persent = self::instance()->get('cmd_persent'); $this->cmd_stack = self::instance()->get('cmd_stack'); if(!empty($this->cmd_stack) && $this->persent > 0){ $command = $this->cmd_stack[--$this->persent]; self::instance()->set('cmd_persent', $this->persent); return $command; } return null; } public function get_redo_command(){ $this->persent = self::instance()->get('cmd_persent'); $this->cmd_stack = self::instance()->get('cmd_stack'); if(!empty($this->cmd_stack) && $this->persent < count($this->cmd_stack)){ $command = $this->cmd_stack[$this->persent++]; self::instance()->set('cmd_persent', $this->persent); return $command; } return null; } }
Befehlsbasisklassenimplementierung:
namespace woo\command; require_once('../memento/state.php'); require_once('../memento/memento.php'); abstract class Command { protected $state; final function __construct(){ $this->state = new \woo\memento\State(); } function execute(\woo\controller\Request $request) { $this->state->set('request', $request); $this->do_execute($request); } abstract function do_execute(\woo\controller\Request $request); function do_unexecute(\woo\controller\Request $request) {} public function get_state(){ return $this->state; } public function set_state(State $state){ $this->state = $state; } public function get_request(){ if(isset($this->state)){ return $this->state->get('request'); } return null; } public function set_request(\woo\controller\Request $request){ if(isset($this->state)){ return $this->state->set('request', $request); } } public function create_memento(){ \woo\base\SessionMementoTaker::push_command($this); $mem = new \woo\memento\Memento(); $mem->set_state($this->state); return $mem; } public function set_memento(Memento $mem){ $this->state = $mem->get_state(); } }
Der letzte Schritt besteht darin, Undo-Redo zu implementieren. Hier betrachte ich Undo/Redo als eine normale Befehlsanforderung, ohne dass eine zusätzliche Verteilungsverarbeitung im Controller erforderlich ist.
Rückgängig-Befehl:
class State{ private $values = array(); function __construct(){ } public function set($key, $value){ $this->values[$key] = $value; } public function get($key){ if(isset($this->values[$key])) { return $this->values[$key]; } return null; } }
namespace woo\command; require_once('request.php'); require_once('command.php'); require_once('../base/registry.php'); require_once('../file_manager.php'); require_once('../base/session_memento.php'); class CopyCommand extends Command { function do_execute(\controller\Request $request) { $src_path = $request->get_property('src'); $dst_path = $request->get_property('dst'); $this->state->set('src_path', $src_path); $this->state->set('dst_path', $dst_path); $this->create_memento(); $file_manager = \base\Registry::file_manager(); $ret = $file_manager->copy($src_path, $dst_path); $request->add_feedback($ret); //... } }
Das Ende.
Das Obige stellt die vollständige Implementierung von Redo und Undo vor, einschließlich der relevanten Aspekte. Ich hoffe, dass es für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.