Factory Klassen

dg87

Erfahrenes Mitglied
Guten Tag

langsam ist es mir echt peinlich, da ich in letzter Zeit so oft frage.
Ich mein ich hab bei Google eben auch wieder geschaut und ja es stehen viele Seiten da, aber iwie fehlt mir auch da wieder ein Bezug.

Was bringen mir eigentlich Factory Klassen. Sie erzeugen Objekte klar.
Angenommen ich hätte diese nicht und erzeuge immer Objekte (überall) mit dem new Operator.
Wenn nun bei einem Konstruktor ein neues Argument dazukommt, muss ich das bei jeder Klasse ändern. Bei einer Factory Klasse mache ich das nur da drinnen, d.h. nur einmal und muss nicht den ganzen Code ändern.

Habe ich das richtig verstanden?
Wenn nicht, bitte ganz einfach, warum sollte ich meine Objekte von einer Factory Klasse erzeugen lassen?

Vielen Dank
 
Dieses Entwurfmuster dient eigentlich nur dazu, dass du von einer bestimmten Klasse eine Instanz erstellst und von dieser Instanz gleichzeitig weitere Methoden aufrufen kannst. Das muss nicht sein, aber wenn du ein größeres Projekt hast, in welchem du oft eine Instanz von dieser Klasse erstellst und immer am Anfang die gleichen Methoden aufrufst, dann musst du es nur einmal in der Factory-Klasse ändern und nicht bei jedem einzelnen Initialisieren.
 
Also eigentlich wird die Factory dafür gebraucht, Objekte zu erzeugen, bei denen zur Entwicklungszeit noch nicht klar ist, welche Klasse denn nun eigentlich verwendet werden soll. Dafür akzeptiert die Factory in PHP als erstes Argument einen String, der den Klassennamen des zu erzeugenden Objekts beinhaltet. Über Reflection wird dann in der Factory das jeweilige Objekt erzeugt und zurück gegeben.

Kurz: Verwende eine Factory, wenn zur Laufzeit erst entschieden werden soll, welcher Typ das Objekt sein soll.
 
Ok das vom Saftmeister hab ich verstanden.
Aber wenn man das zB auf das Factory-Method-Pattern auslegt check ich es wieder ned.

Einfach gesagt, warum sollte ich eine Factory Klasse nutzen. Warum soll ich meine Objekte über eine Factory Method erstellen lassen. Ein Kollege hier aus dem Forum (weiß den Namen nicht mehr, ist aber auch fast immer da), hat auch letztens eine für einen Query benutzt.
Ich versteh nur nicht, warum ich diese Dinger brauchen soll?
 
Datenbank-Zugriff ist ein gutes Beispiel für Factory-Instanzen.

Wenn du einen Datenbank-Abstraktionslayer bauen willst, also quasi eine einheitliche Schnittstelle um auf grundsätzlich verschiedene Datenbanksysteme (bspw. MySQL, MSSQL, PostgreSQL, etc) zugreifen zu können. Beispiel:

PHP:
$databaseType = "MySQLDatabase";

// Verbindungsintanz holen
$dbinstance = Database::factory($databaseType, $connectionParameters);

// Verbindung herstellen
$dbinstance->connect();

Dazu müsste eine Klasse mit dem Namen "MySQLDatabase" existieren, von der dann innerhalb der factory-Methode eine Instanz erstellt wird:

PHP:
class Database
{
   /*Membervariablen, etc...*/

  /**
   * Erstelle eine neue Datenbank-Verbindungsinstanz
   * @return DatabaseInterface
   */
  public static function factory($type, $params)
  {
     /// Hier Reflectioncode. Vereinfacht:
     $newInstance = new $type;
     $newInstance->setParams($params);

     return $newInstance;
  }
}

Die Factory-Methode wird dann als Rückgabewert sinnvollerweise ein Interface zurückgeben, welches von der Klasse MySQLDatabase implementiert werden muss:

PHP:
interface Database_Interface
{
  public function setParams();
  public function connect();

  ... Weitere Methoden ...
}

class MySQLDatabase implements Database_Interface
{
  public function setParams(array $params)
  {
    // Hier irgendwas mit den Parametern machen
  }

  public function connect()
  {
    // Hier Verbindung herstellen...
  }

  ... Weitere Methoden ...
}

Vielleicht ist es besser ein Beispiel zu haben, das man auseinander nehmen kann. Können wir deine Fragen daran klären?
 
Ok, ich schreib das mal vom Buch ab, was mich so stutzig gemacht hat. Ich lese PHP Design Pattern derzeit und da ist eben das Erzeugungsmuster Factory-Method-Pattern. Mir erschließt sich da der Sinn nicht.

Vorneweg nochmal. Dein Beispiel mit der Datenbank war sehr deutlich und gut, das wäre für mich schlüssig. Lass mich kucken ob ich es verstanden habe:
Je nachdem welche Datenbank wir haben (die du ja übergibst) erzeugt die Factory die entsprechenden Objekte. - Das war einfach ausgedrückt aber ich denke das triffts.
Das ist echt supe das Beispiel, das hilft mir grad sehr weiter, denn jetzt hab ich zumindest mal einen Sinn von den Dingern erkannt.

Jedoch das vom Buch mit dem Erzeugungsmuster ist mir nicht klar, ich poste hier mal den Code.
Kurz zum Hintergrund, es geht im Buch immer über ein Autogeschäft, das Autos verleiht oder verkauft.
Aber nun endlich zum Code:
PHP:
<?php
	abstract class AbstractManufacturer
	{
		protected $name;
		
		public function __construct($name)
		{
			$this->name = $name;
		}
		public function sellVehicle($color)
		{
			$vehicle = $this->manufactureVehicle($color);
			$vehicle-> startEngine(); // Folgende Methoden werden vom Interface Vehicle bereitgestellt; 
			$vehicle->moveForward();
			$vehicle->stopEngine();
			
			return $vehicle;
		}
		
		abstract protected function manufactureVehicle($color);
	}
	
	class Carmanufacturer extends AbstractManufacturer
	{
		protected function manufactureVehicle($color)
		{
			$vehicle = new Car($this->name, $color); // Car hat das Interfrace Vehicle implementiert
			return $vehicle;
		}
	}
	
	
	
	$bmwManufacturer = new Carmanufacturere('BMW');
	$bmw = $bmwManufacturer->sellVehicle('blau');
?>

ist halt blöd jetzt für euch, weil ich halt die Beschreibung und das vorherige vom Buch fehlt.
Aber ich seh da keinen Vorteil.

Am Schluss heißt es halt:
Das Fabrikmethoden Muster definiert eine Schnittstelle zur Erzeugung von Objekten. Es verlagert aber die eigentliche Instanziierung in Unterklassen (was bringt mir das****). Es lässt die Unterklassen entscheiden, welche konkreten Implementierung nötig sind.


Wie gesagt, das mit der Datenbank hab ich ja oben nochma richtig interpretiert oder. Da seh ich durchaus einen Sinn. Aber bei dem Pattern nicht...

Ich geh ins Bett, hab die Schnauze heute voll von dem Buch, morgen wieder weiter :-)
Danke schon ma
 
Zuletzt bearbeitet:
Mh, immer diese blöde Auto-Beispiel. Das war der Grund dafür, weshalb ich OOP erst ein halbes Jahr später als ich es hätte können, verstanden habe. Das die sich darauf immer so versteifen.
 
Als Kurzbeschreibung steht im Buch: delegiert die Erzeugung von Objekten an unterklassen. Ich seh da keinen Vorteil und das hat nichts mit dem Datenbank Beispiel zu tun (was ich aber immer noch perfekt finde weil das für mich den Sinn allgemein von Factory Klassen zeigt)

Achja und zu guter letzt steht da noch es fördert die Programmierung gegen Schnittstellen ...
 
Grundsätzlich macht dieses Auto-Beispiel das Gleiche wie mein Beispiel. Angenommen, das Auto "Car" wäre eine abstrakte Klasse, eine konkrete abgeleitete Klasse davon wäre BMW oder meinethalben auch Opel. Dann könnte man in der <Fabrik> entweder einen BMW oder auch einen Opel bauen.

Das Auto-Beispiel ist vor allem für die Leute verständlich, die OOP schon verstanden haben. ABER! genau da setzt OOP an. Die Objekte sollen nicht als Variablen gesehen werden sondern ein virtuelles Irgendwas von etwas Realem.

Hier mal wieder ein schönes Zitat aus einem Buch (Treiberprogrammierung unter Linux): "OOP beginnt nicht mit der Programmmiersprache sondern im Kopf des Entwicklers."

Genauso musst du das Thema angehen. Versuche, wenn du das verstehen willst, dir ein Beispiel aus dem realen Leben vorzustellen, und dann zu überlegen, wie das in einer Programmiersprache abzubilden ist.

Ich will dazu noch was loswerden. So ein Buch "Design-Pattern in $Programmiersprache" ist - nur um es zu lernen - echt schlecht geeignet. Da muss man ausprobieren. Und dazu braucht man Phantasie, sich ein kleines Projekt zu überlegen, das umzusetzen.

Warum tut man sich das "einfach so" an? Ich habe Design-Patterns dadurch gelernt, das ich sie angewendet habe. Da war dann irgendwann der Gedanke: Mensch, das muss doch eleganter gehen.
 
Bücher über Entwurfsmuster sind praktisch als Nachschlagewerk, wenn man, wie saftmeister schon sagte, an eine Stelle kommt, wo man sich überlegt, dass die eigene Lösung nicht das Non-Plus-Ultra sein kann.
 
Zurück