OO Ansatz für Strategie Spiel - Designfrage
-
Ui! Danke wiedermal.
Hätt ich nicht erwartet dass Du mir gleich den Code servierst, super
Sieht wirklich nett aus

Hab mein Compiler grad nicht dabei, versuchs grad im Kopf einzubauen.
Ist id_type ein Typ von Boost, oder ist der zum Selberbasteln?
Was meinst Du mit "meine normale Registerfunktion"? Hab ich bis jetzt gar keine.
Meine Implementation sieht momentan etwa so aus: http://www.c-plusplus.net/forum/viewtopic-var-t-is-153908.html
-
Nuja, da hast du Creators und Products. Ich seh da keine Factory.
id_type sollte normalerweise ein typedef auf einen entsprechenden Template-Parameter sein, ist meistens ein int oder string. Ziel des Factory-Patterns in diesem Zusammenhang wäre ja so ein Aufruf:player.build ("Farm", location); // entspricht (nach ggf. nötigen Prüfungen) in etwa player._buildings.append (factory("Farm") (location)); // oder player._buildings.append (factory.create ("Farm", location));wobei _buildings z.B. vom Typ ptr_vector<Building> wäre. Damit so etwas funktioniert, musst du die Typen, die die Factory ausspuckt erst registrieren. Schau dir mal die Implementierung aus Loki an (lass dich nicht von den ganzen typedefs und Überladungen abschrecken, das wichtige ist relativ übersichtlich unten) und besorg dir vielleicht auch das zugehörige Buch.
-
Hmm, da hab ich wohl was nicht komplett verstanden. Das UML Diagramm auf Wikipedia und anderen Seiten hat eben nur 4 Klassen Creator und Product plus die konkreten Ableitungen.
Da weiss ich ja nun was ich zu lesen hab
Danke mal soweit, ich hab sicher bald die nächste Frage..
-
.filmor schrieb:
..Damit so etwas funktioniert, musst du die Typen, die die Factory ausspuckt erst registrieren. Schau dir mal die Implementierung aus Loki an (lass dich nicht von den ganzen typedefs und Überladungen abschrecken, das wichtige ist relativ übersichtlich unten) und besorg dir vielleicht auch das zugehörige Buch.
Puh abschrecken ist gut, es verwirrt auf jedenfall ganz schön. Ich kapiers irgendwie nicht. Kennst Du nicht eine andere gute Bsp. Implementierung?
Oder ev. kannst Du mir noch mal mit etwas Code helfen, zur Factory?
Wäre spitzenmässig!
-
Zeig was du hast. Jetzt bin ich zu Hause, da hab ich meine "eigene" Implementierung auch zur Hand

-
Eingentlich nur das hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-153908.html nur gibt create() jetzt nen Zeiger zurück plus eine zusätzliche ConcreteProductB und ConcreteCreatorB, und die abgeänderte Main():
vector<Creator*> creators; Creator* creatorA = new Concrete_Creator(); Creator* creatorB = new Concrete_CreatorB(); Creator* creatorC = new Concrete_Creator(); creators.push_back( creatorA ); creators.push_back( creatorB ); creators.push_back( creatorC ); for( vector<Creator*>::iterator it = creators.begin(); it != creators.end(); it++ ) { Product* product; product = (*it)->create(); product->say_hello(); delete product; } delete creatorA; delete creatorB; delete creatorC;ISt übrigends Factory Method, meintest Du ne Abstract Factory? Weil das blick ich noch gar nicht.
-
Aber hey, nur wenn Du magst. Ev. krieg ichs mit ner einfachen Erklärung selber hin. Nur steh ich grad aufm Schlauch, was das registrieren betrifft.
-
Offensichtlich gibt es verschiedene Meinungen darüber, was eine Factory ist ;). Naja, hier mal das, was ich immer verwenden (entspricht quasi der Loki-Version, aber ohne die Überladungen für die Konstruktorparameter:
// factory.hpp #ifndef YDONEUM_FACTORY_FACTORY_HPP #define YDONEUM_FACTORY_FACTORY_HPP #include <map> #include <boost/function/function0.hpp> #include "policies/DefaultErrorPolicy.hpp" namespace ydoneum { template < class AbstractProduct, typename IdentifierType, typename ProductCreator = boost::function0<AbstractProduct*>, template <typename, class> class ErrorPolicy = policies::factory::DefaultErrorPolicy > class factory : public ErrorPolicy<IdentifierType, AbstractProduct> { public: typedef std::map<IdentifierType, ProductCreator> MapType; bool register_product (const IdentifierType& id, ProductCreator creator) { return _map.insert (MapType::value_type (id, creator)); } bool unregister (const IdentifierType& id) { return _map.erase (id) == 1; } /// \todo create would be more useful, if it could handle constructor /// arguments AbstractProduct* create (const IdentifierType& id) const { typename MapType::const_iterator i = _map.find (id); if (i != _map.end ()) return (i->second) (); else return OnUnknownType (id); } protected: MapType _map; }; } #endif// DefaultErrorPolicy #ifndef YDONEUM_FACTORY_POLICIES_DEFAULT_ERROR_POLICY #define YDONEUM_FACTORY_POLICIES_DEFAULT_ERROR_POLICY #include <exception> namespace ydoneum { namespace policies { namespace factory { template <typename IdentifierType, class AbstractProduct> struct DefaultErrorPolicy { public: class Exception : public std::exception { public: Exception (const IdentifierType& id) : _id (id) {} virtual const char* what () { return "Unknown Type"; } const IdentifierType& getId () { return _id; } ~Exception () throw () {} private: IdentifierType _id; }; protected: AbstractProduct* OnUnknownType (const IdentifierType& id) const { throw Exception (id); return 0; } }; } } } #endifkA, ob das funktioniert, ich habs glaub ich noch nie verwendet, weil ich immer halt Parameter brauchte und die deckt das Ding halt nicht ab...
-
Hi
War gestern noch unterwegs..Danke für den Codeschnippsel.
Hab mir das jetzt mal in ruhe angeschaut, aber ich schnall nicht alles.
Das mit dem registrieren ist jetzt klar. Aber vor allem diese zwei Template Parametertypename IdentifierType, typename ProductCreator = boost::function0<AbstractProduct*>,kapier ich nicht. Der zweite ist ja mit default belegt. Muss ich da ein ()-Operator in die AbstractProduct Klasse einbauen für den Functoraufruf?
Und was käme bei Id.Type rein? Ein enum mit all meinen Concrete Products?Irgendiwe fehlt mir noch ein bisschen der Überblick des Gesamtaufbaus..
-
IdentifierType ist etwas, was das Produkt eindeutig identifiziert. Es kann praktisch alles sein, was einen definierten < und ==-Operator (für std::map) besitzt. Ein enum ist zum Beispiel in diesem Fall sinnvoll, weil die Anzahl der Gebäude bekannt ist und sich im Verlauf der Entwicklung kaum verändern wird.
Der ProductCreator ist praktisch dein Creator, er ist als Template-Parameter gehalten, damit man auch etwas anderes als boost::function (z.B. Loki::Functor) verwenden kann. Das es eine Standardzuweisung hat solltest du dich darum nicht kümmern, wenn du Boost hast. boost::function akzeptiert jeden Funktionstyp (auch Funktionsobjekte) mit der entsprechenden Signatur (nimmt keine Argumente und liefert einen Zeiger auf AbstractProduct zurück).
-
Hey Danke .filmor
Ist echt spitzenmääässig, habs nun endlich alles geschnallt und zum laufen gekriegt.
Auch den netten Aufruf per generischem Creator in der Form:factory.register_product < ProductA > ( "ProductA" );Werd ich nun alles mal zusammenwurschteln und das mit den Gebäuden angehen.
Big Thx
