Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

1

19.04.2016, 18:12

Factory Pattern | Was ist der Sinn dahinter?

Hi,
ich schaue mir gerade ein paar Design Pattern an. Und komme gerade über einen alten Bekannten:
Factory Pattern.

Ich lese zwar immer wieder die Beschreibung, was das ist, jedoch kann ich den Sinn dahinter nicht nachvollziehen.
Könnte mir jemand diesen Erläutern?

LG Julien

P.S.: Hat jemand einen Buchtipp wie ich den richtigen Einsatz von Designpattern lernen kann?
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Julién« (19.04.2016, 18:21)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

19.04.2016, 18:23

Lose Kopplung. Stell Dir folgenden Fall vor:
Du hast eine Klasse A, die eine Datenbankverbindung aufmacht, Zeug lädt und damit irgendwas tut. Dazu erzeugt sie eine Datenbankverbindung. Nun willst Du die Klasse A testen, bzw. das, was sie mit den Daten tut. Aber natürlich willst Du für den Test keine Datenbank. Nun, was tun? Würde Klasse A nicht selbst eine Verbindung erzeugen, sondern z.B. eine Factory nach einer Verbindung fragen, könnte in deinem Test die Factory einen Mock liefern, der zwar Daten ausspuckt und so tut als wäre es eine Datenbank, aber gar keine ist. Damit sind die Tests viel einfacher zu bauen und die Klasse auch ohne Datenbank schon prima testbar.
Factories sind nicht nur für Tests praktisch, sondern auch für diverse andere Dinge. Du bist damit wesentlich flexibler, weil Du eigentlich nur ein Produkt haben willst, was sich so und so verhält. Was genau da unten drunter steckt, ist Dir eigentlich egal. Du kannst bei gutem Einsatz die Kopplung reduzieren, die Abhängigkeiten lösen oder vom Benutzer lauter Dinge verstecken, die er sonst irgendwie kennen müsste.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

3

19.04.2016, 18:23

Hat jemand einen Buchtipp wie ich den richtigen Einsatz von Designpattern lernen kann?

http://www.amazon.de/dp/0596007124/sppro-21
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

4

19.04.2016, 18:27

Welches Pattern genau meinst du? Factory Method oder Abstract Factory? Welche Beschreibung hast du bisher gelesen?

Meiner Meinung nach sind die Struktur- und Verhaltensmustser die wichtigsten, vielleicht solltest du deinen Fokus eher auf diese Schwenken.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

5

19.04.2016, 18:30

Primär beziehe ich mich jetzt auf 'Factory Method'. Ich fände es auch cool, wenn jemand mir zu gleich erklären könnte wozu 'Abstract Factory' dient :thumbsup:

@Nimelrian: Ich suche gleich mal alle Buchläden ab, und lese es mal an. Danke für den Tipp :thumbsup:

@BlueCobold: Hättest du ev. ein Beispiel, das zeigt wie ich mit einer Factory eine lose Kopplung erreichen kann? Ich kann's mir nicht so recht vorstellen.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Julién« (19.04.2016, 18:36)


KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

6

19.04.2016, 18:39

Für das P.S, wenn es spezielle um Spieleprogrammierung geht:
http://gameprogrammingpatterns.com/contents.html

Wurde hier ja schon öfters genannt. Ist ein netter Überblick!
WIP Website: kevinheese.de

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

20.04.2016, 01:45

Der Zweck der Factory Method, wenn ich es richtig verstanden habe, ist eine Steigerung der Austauschbarkeit. Denkbar wäre beispielsweise ein Spawner, der bestimmte Objekte in einem Spiel spawnen soll. Der Spawner selbst würde sich darum kümmern, immer den richtigen Zeitpunkt für das Spawnen zu bestimmen und mit Hilfe der Factory würde er das Objekt tatsächlich erzeugen. Gerade wenn die Erzeugung komplex wird, bspw. weil einige Parameter notwendig werden, die von der Factory zwischengespeichert werden können, wäre dieses Pattern überlegenswert. (Es kann auch sein, dass kein Objekt einer abgeleiteten Klasse erzeugt wird, sondern ein Objekt mit einer bestimmten Komposition anderer Objekte.)
Der Spawner benötigt nur eine Factory, die ein "Objekt" bzw. "Spielobjekt" liefert. Die Factory kann dabei eine für "Bogenschützengegner", "leichte Kriegsschiffe" oder "Lebensenergie" sein. dem Spawner ist der konkrete Typ egal, solange es "Spielobjekte" sind, die erzeugt werden.
(Ich muss zugeben, dass es mir schwer fällt, einen Unterschied zwischen den beiden Patterns zu finden, da die Abstract Factory augenscheinlich einfach nur mehrere Produkte unterschiedlichen Basistyps liefern könnte. Entsprechend wirkt dieses Pattern für mich eher wie eine leichte Erweiterung der Factory Method.)

Abgesehen von den Entwurfsmustern gibt es ein paar Prinzipien, die vielleicht noch interessant sein könnten.
Inversion of Control bspw. besagt, dass ein Objekt sich nicht selbst um das Auflösen von Abhängigkeiten kümmern soll, sondern diese von außen zugewiesen bekommen sollte.
Ein "Component Based System" wird häufig verwendet, um "Composition over Inheritance" umzusetzen. Letzteres besagt, man solle keine unnötigen Vererbungsstrukturen erstellen, wenn auch Kompositionen verwendet werden könnten.

Wichtig ist vor allem aber abzuschätzen, wann man tatsächlich ein bestimmtes Pattern anwenden sollte und wann man darauf verzichten kann.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

8

20.04.2016, 09:01

Blue hat es schon umfassend erklärt ;).

Wenn man es vielleicht vereinfacht ausdrückt: Verschiedene Implementierungen einer Schnittstelle an Hand einer Methode erstellen. Allerdings verwende ich das Pattern bei Spielen auch relativ selten.

Ein Anwendungsfall, der sich bei mir angeboten hatte, war ein Entity Component System. Es gibt eine Menge von Klassen, die von EntityComponent erben und über JSON initialisierbar sind. Dabei wird also ein Objekt speziellen Typs erstellt und immer mit einem JSON-Objekt initialisiert. Das schreit für mich nach einer EntityComponentFactory. Diese hat eine Methode EntityComponent CreateComponent(JsonData data). Das JsonData hat eine ID, die den Typ der EntityComponent erkennt und das Objekt vom richtigen Typ anlegt und dabei das JSON-Objekt übergibt. Dadurch kann man echt elegant ein Entity aus JSON mit einem foreach und der Factory erstellen:

C#-Quelltext

1
2
3
4
5
6
var entity = new Entity();
foreach(var entityComponentJsonData in entityJson.Components)
{
    var component = EntityComponentFactory.CreateComponent(entityComponentJsonData);
    entity.AddComponent(entity);
}


Code habe ich jetzt frei aus dem Kopf getippt.

LInsoDeTeh

Treue Seele

Beiträge: 372

Wohnort: Essen, Deutschland

Beruf: Team Lead Inhouse-Entwicklung

  • Private Nachricht senden

9

20.04.2016, 09:15

Ein Praxisbeispiel:
Wir hatten mal den Anwendungsfall, Daten von A nach B transportieren zu müssen, zum Beispiel Artikel, Werbung, und andere Daten, die komplexe Entitäten waren. Wir bekamen über eine Queue lediglich einen Synchronisationsauftrag mit dem Entitätentyp und den Primary Keys.
Basierend auf dem Entitätentyp mussten verschiedene Synchronisationslogiken greifen, denn ein Artikel wurde mit anderer Geschäftslogik transportiert, als eine Werbung. Insgesamt gab es ca. 12 verschiedene Implementierungen für verschiede Business Objekte.
Also gab es Factories, die abhängig vom Entitätentyp passende Implementierungen von uns definierten Interfaces ISynchronizer, IPropertyMapper, etc. zurückgeliefert hat. Eine weitere Factory hat die entsprechenden Datenbankverbindungen zurückgegeben, die basierend auf dem Auftragstyp unterschiedlich sein konnten.

Statt also einen Einstiegspunkt zu haben, der if else if else if else in 12-facher Ausführung macht, gibt dir die Factory die für deinen Fall benötigte Implementierung und die wird nur noch aufgerufen.

So kannst du, wie BlueCobold schon geschrieben hat, in Unit Tests die Queue- und Aufruflogik testen und die Factory mocken, sodass du Aufrufe auf ihr prüfen kannst, oder sie selbst Mocks der Implementierungen zurückgibt, um deren Aufrufe zu testen, usw.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

20.04.2016, 09:42

Eine Factory erlaubt dir die Erzeugung von Objekten, die du zur Compile-Zeit noch gar nicht kennst - quasi wie ein Konstruktor, bei dem der Typ des zu erzeugenden Objekts ein Parameter ist.

Praktisches Beispiel aus der Spieleentwicklung: Du liest eine Level-Datei ein, in der die im Level enthaltenen Objekte beschrieben sind. Jetzt steht da in der Datei sinngemäß "erzeuge ein Objekt vom Typ 'EvilClown' an der Position 47, 11". Anstatt nun eine ellenlange Liste von Fallunterscheidungen à la "if(objectType == "EvilClown") addObject(new EvilClown());" zu verwenden (was gar nicht möglich wäre, wenn zur Laufzeit neue Typen dazukommen können, z. B. über Erweiterungen/Plugins), gibst du einfach den String "EvilClown" an eine Factory, die dir dann das Objekt erzeugt und als Zeiger auf die Basisklasse zurückliefert. Der Code, in dem der Level geladen wird, muss also gar nicht wissen, welche Objekttypen es gibt.

Werbeanzeige