Heim > Backend-Entwicklung > PHP-Tutorial > Vollständige Implementierung von Redo und Undo

Vollständige Implementierung von Redo und Undo

WBOY
Freigeben: 2016-08-08 09:32:36
Original
979 Leute haben es durchsucht
Das Rückgängigmachen und Wiederherstellen erfordert zur Unterstützung den Memo-Modus und den Befehlsmodus. Ich habe bereits einige Grundkenntnisse über den Befehlsmodus und den Erinnerungsmodus erworben. Hier müssen wir die beiden Modi kombinieren, um ein Modul für Undo-Redo-Operationen zu implementieren, um das erlernte Wissen zu festigen.

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);
	}
}
Nach dem Login kopieren
Durch die Deklaration des Konstruktors als privat ist der Controller ein Singleton.

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;
	}
}
Nach dem Login kopieren

Die Implementierung von SessionMementoTaker basiert auf a zuvor implementierte Sitzung (URL-Registrierungsmechanismus). Durch die Wiederherstellung verschiedener Objektdaten basierend auf der in Cookies gespeicherten Sitzungs-ID kann der Zweck erreicht werden, dass derselbe Benutzer mehrmals Zugriff auf dieselben Objektdaten anfordert. SessionMementoTaker bietet drei zusätzliche Schnittstellen. Die Operation push_command fügt Befehle zur historischen Befehlsliste hinzu. Die maximale Länge der Verlaufsbefehlsliste beträgt 5. Wenn sie 5 überschreitet, wird der erste Befehl entfernt. Darüber hinaus entspricht push_command dem Hinzufügen eines neuen Befehls und dem Verschieben des Befehlszeigers (Persent) an die neueste Position. Den vorherigen Zustand verwerfen. get_undo_command ruft den zuletzt ausgeführten historischen Befehl ab und aktualisiert den Zeiger, das Gleiche gilt für get_redo_command.
Historische Befehlsliste: command1---command2---command3---* Das Sternchen zeigt an, dass es dauerhaft ist und auf den zuletzt auszuführenden Befehl verweist.
Eine Rückgängig-Operation: command1---command2-*--command3--- Nach dem Rollback bewegt sich der persistente Zeiger rückwärts.
Eine Rückgängig-Operation: command1--*command2----command3--- Nach dem Rollback bewegt sich der persistente Zeiger rückwärts.
Ein Redo-Vorgang: command1---command2-*--command3--- Nach dem Redo bewegt sich der persistente Zeiger vorwärts.
push_command: command1---command2---command3---command4---* persist wird auf das Frontend aktualisiert
Hier wird ein einzelnes Befehlsobjekt als Urheber (Originator) betrachtet. Erstellen Sie bei Bedarf aktiv ein Andenken (Memento), um den aktuellen internen Status zu speichern, und fügen Sie das Befehlsobjekt in die Liste der historischen Befehlsdatensätze ein.

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();
	}
}
Nach dem Login kopieren

Die Befehlsaufgabe speichert die Parameter des angeforderten Befehls zu Beginn der Ausführung . Auch andere notwendige Parameter können während der Ausführung gespeichert werden. Da einige Befehle keine Rückgängig-Vorgänge unterstützen, wird in der übergeordneten Klassenimplementierung ein leerer Unexecute-Befehl verwendet Die vom Befehlsobjekt zu erledigende Aufgabe ist relativ einfach: Parameter (Verifizierungsparameter) abrufen, die erforderlichen Statusinformationen speichern und die Steuerung an bestimmte Geschäftslogikobjekte übertragen. Ausführungsergebnisse hinzufügen und zurückgeben. Verschiedene Befehle erfordern unterschiedliche Anforderungsparameter. Einige Befehle erfordern oder unterstützen den Rückgängig-Vorgang überhaupt nicht, sodass der Vorgang „create_memento“ selektiv ausgeführt werden kann.

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;
	}
}
Nach dem Login kopieren

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);
		//...
	}
}
Nach dem Login kopieren
Wiederholen-Befehl:


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.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage