über mich

Hallo, mein Name ist Heiko Dreyer. Ich arbeite freiberuflich als Webdesigner und Entwickler mit Schwerpunkt Flash/Flex, PHP und Cocoa Touch.

Brauchen Sie Hilfe bei Ihrem Webdesign oder suchen Sie einen Entwickler? Ich stehe Ihnen jederzeit mit meinen Fähigkeiten zur Verfügung.

über boxedfolder

Mein Blog bieten Überblick über sämtliche Neuigkeiten und Workflows mit denen ich mich beschäftige.

Aktuell bin ich vermehrt im Bereich Webentwicklung, sprich Flash/Flex und PHP tätig. Darüber hinaus blogge ich auch über Anwendungsentwicklung mit AIR für den Desktop und Cocoa Touch für die Mobile Plattform.

Composite & Command: Undo-Funktion noch flexibler

In dem vorherigen Artikel über das Command-Pattern, hab ich eine kleine Beispielanwendung vorgestellt. Diese demonstriert wie man mit Hilfe des Command-Entwurfmusters ganz leicht eine Undo-Funktion entwerfen kann. Wie bereits angekündigt, möchte ich in diesem Eintrag noch einmal kurz in die besprochene Anwendung schauen und das ganze mit dem Composite-Pattern strukturell etwas erweitern um sie noch einmal in ihrer Flexibilität aufzubessern.

In der überarbeiteten Version unserer Anwendung geht es nun darum, dass es die Möglichkeit gibt den Kreis nicht nur in x- und y-Richtung zu bewegen, sondern auch dessen Alpha-Wert anzupassen.

Get Adobe Flash player

(Rechtsklick-View Source um Quellcode einzusehen)

In diesem Beispiel brauchen wir also neben dem MoveCommand noch einen zweiten Befehlstypen, welcher in der Lage ist den Alpha-Wert eines entsprechenden Sprites zu verändern und wieder rückgängig zu machen. Er muss also das ICommand-Interface implementieren.

AlphaCommand.as:

package com.boxedfolder.examples.undo
{
	import flash.display.Sprite;

	public class AlphaCommand implements ICommand
	{
		private var _sprite:Sprite;

		private var _alpha:Number;

		private var _targetAlpha:Number;

		public function AlphaCommand(sprite:Sprite, targetAlpha:Number)
		{
			_targetAlpha = targetAlpha;
			_alpha = sprite.alpha;
			_sprite = sprite;
		}

		public function execute():void
		{
			_sprite.alpha = _targetAlpha;
		}

		public function undo():void
		{
			_sprite.alpha = _alpha;
		}
	}
}

Um eine Struktur zu erhalten, die es uns ermöglicht viele kleinere Commands sequentiell abzuarbeiten, bedienen wir uns des Composite-Patterns. Wir erstellen uns dazu einen MacroCommand, welcher potentiell beliebig viele Unterbefehle einschließen kann.

MacroCommand.as:

package com.boxedfolder.examples.undo
{
	public class MacroCommand implements ICommand
	{
		private var commandStack:Array = [];

		public function execute():void
		{
			var command:ICommand;

			for(var i:int = 0; i < commandStack.length; ++i)
			{
				command = commandStack[i] as ICommand;
				command.execute();
			}
		}

		public function undo():void
		{
			var command:ICommand;

			while(commandStack.length > 0)
			{
				command = commandStack.pop() as ICommand;
				command.undo();
			}
		}

		public function addSubCommand(command:ICommand):void
		{
			commandStack.push(command);
		}
	}
}

Da die Klasse MacroCommand das Interface ICommand implementiert ist eine Instanz in der Lage wie ein regulärer Befehl aufgerufen zu werden. Anstatt allerdings selber Funktionalität zu implementieren, wird durch die Unterbefehle iteriert und deren execute()- bzw. undo()-Methode ausgeführt. Zusätzliche Subcommands lassen sich via der Methode addSubCommand() hinzufügen.

Um jetzt diese Befehlskette in unsere Anwendung zu integrieren, müssen wir den MacroCommand instantiieren, Subcommands hinzufügen und dessen execute()-Methode aufrufen.

UndoExample.as:

package
{
	import com.boxedfolder.examples.undo.AlphaCommand;
	import com.boxedfolder.examples.undo.ICommand;
	import com.boxedfolder.examples.undo.MacroCommand;
	import com.boxedfolder.examples.undo.MoveCommand;

	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;

	[SWF(height="550", width="550", backgroundColor="#ffffff", frameRate="50")]

	public class UndoExample extends Sprite
	{
		//... verkürzt

		private var commandStack:Array = [];

		public function UndoExample()
		{
			setupVisuals();
		}

		private function setupVisuals():void
		{
		     //....verkürzt
		}

		private function buttonHandler(e:MouseEvent):void
		{
			if(e.target == goButton)
				changeObject();

			if(e.target == undoButton)
				undo();
		}

		private function changeObject():void
		{

			var command:MacroCommand;
			var yv:Number = Number(yTextField.text);
			var xv:Number = Number(xTextField.text);
			var av:Number = Number(aTextField.text);

			if(!isNaN(yv) && !isNaN(xv) && !isNaN(av))
			{
				command = new MacroCommand();
				command.addSubCommand(new MoveCommand(circle, xv, yv));
				command.addSubCommand(new AlphaCommand(circle, av));

				commandStack.push(command);
				command.execute();
			}
		}

		private function undo():void
		{
			var command:ICommand;

			if(commandStack.length > 0)
			{
				command = commandStack.pop() as ICommand;
				command.undo();
			}
		}
	}
}

Der Vorteil dieser Struktur liegt in der Flexibilität. Wir verwenden einfach mehreren MacroCommands um so Funktionalität zu bündeln und den kompletten Befehlsverbund leicht Rückgängig zu machen.

30. November 2009 (12:01 Uhr) - design patterns, flash & flex, web nach oben

Bookmarks »


  • del.icio.us
  • Digg
  • Technorati
  • MisterWong.DE
  • Furl
  • Facebook
  • Live
  • Google
  • Sphinn
  • Mixx
  • NewsVine
  • BlinkList
  • co.mments
  • YahooMyWeb
  • Spurl
  • blogtercimlap
  • blogmarks
  • StumbleUpon
  • Ma.gnolia


0 Kommentare »