Jun 07

Wenn man sich eingehender mit MVC beschäftigt stellt man fest, dass es ziemlich schwierig ist die Schichten so anzulegen, dass sie vollständig von einander entkoppelt sind. Ein Knackpunkt dabei ist die Datenübertragung. Wie teilt die Business Logic der Präsentationsschicht Daten mit? Hierbei könnte man natürlich auf das gute alte $GLOBALS-Array zurückgreifen. Dies ist zwar eine Lösung aber keine gute. Wir sollten vielmehr die Daten aus einer Schnittstelle beziehen und sie auch dorthin speichern, damit andere Klassen über die fixen Schnittstellen direkt wieder darauf zugreifen können.
Dabei hilft uns das Registry Pattern. Es stellt eine Klasse dar, in der Daten abgelegt und wieder ausgelesen werden können. Hierzu wird für den globalen Zugriff das Singleton Pattern verwendet.
Schauen wir uns nun zunächst das UML-Diagramm an:

Zur Verdeutlichung sind jetzt auch zwei andere Klassen ins Spiel gekommen Client A und B. Diese verwenden die Registry schreibend und lesend, sodass wir die Verwendung der Registry besser nachvollziehen können. Die Registry besteht neben dem Singleton im Prinzip nur aus Verwaltungsmethoden für das Speichern, Löschen, und Zurückgeben von Daten.

Begeben wir uns nun zunächst an die Definition des Interfaces und die Implementation der Registry, bevor wir die Clients auf unsere Daten los lassen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
interface Registry
{
	public static function getInstance ();
	public function register ( $key , $value );
	public function unregister ( $key );
	public function get ( $key );
}
 
class DataLayer implements Registry
{
	protected static $Instance = NULL;
	protected $Registry = array();
 
	protected function __construct ()
	{
 
	}
 
	protected function __clone ()
	{
 
	}
 
	public static function getInstance()
	{
		if ( self::$Instance === NULL )
		{
			self::$Instance = new self;
		}
 
		return self::$Instance;
	}
 
	public function register ( $key , $value )
	{
		$this->Registry [ $key ] = $value;
	}
 
	public function unregister ( $key )
	{
		unset ( $this->Registry [ $key ] );
	}
 
	public function get ( $key )
	{
		return $this->Registry [ $key ];
	}
}

Konstruktor und clone sind wieder zu Gunsten von Singleton deaktiviert bzw. protected deklariert. Die Methoden sollten selbsterklärend sein (wie schon so oft vorher :-) ). Jetzt müssen wir noch die Clients implementieren. Diese sind ganz rudimentär, aber erfüllen in diesem Fall den Demozweck:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Client_A
{
	public function setData ( $Data )
	{
		DataLayer::getInstance()->register ( 'testdata' , $Data );
	}
}
 
class Client_B
{
	protected function getData ( )
	{
		return DataLayer::getInstance()->get ( 'testdata' );
	}
 
	public function printData()
	{
		var_dump($this->getData());
	}
}

Wie wir sehen wird Client_A Daten in die Registry speichern und Client_B diese wieder auslesen und direkt darstellen. Nun müssen wir nur noch ein Testscript schreiben. In diesem werden $Logic und $Display direkt hintereinander instanziiert, das ist in der Regel nicht so :-) .

1
2
3
4
5
6
7
8
9
10
11
$Logic = new Client_A;
$Logic->setData
(
	array
	(
		'foo' => 1,
		'bar' => 2
	)
);
$Display = new Client_B;
$Display->printData();

Wenn wir dieses Script nun ausführen, sehen wir anhand des Outputs, dass alles korrekt funktioniert:

Array
(
[foo] => 1
[bar] => 2
)

Nun haben wir gesehen wie wir Klassen mit Informationen versorgen können, ohne dass sie einander kennen müssen. Die Datenschicht kann, aufgrund fix definierter Schnittstellen beliebig ausgetauscht werden, solange die neue Schicht die selben Schnittstellen implementiert.

Bei Fragen wie gehabt, einfach einen Kommentar hinterlassen (oder auch wenn’s gut war oder geholfen hat?) :-) .

Post to Twitter Post to Delicious Post to Digg Post to Facebook

written by Alexander \\ tags: , , , ,


Leave a Reply

i3Theme sponsored by Top 10 Web Hosting and Hosting in Colombia