Ich bin auf der Suche nach einem tatsächlichen Beispiel für die Verwendung von Factory-Methode Muster in C++. Gibt es ein Quellcode-Beispiel, das eine gute Illustration gibt?Verwendung der Factory-Methode Muster in C++
Antwort
Ich mag, was tut Codeproject lehrt:
http://www.codeproject.com/KB/architecture/FactoryPattBasics.aspx
class CUIFrameWork
{
public:
// Instead of hard coding we write factory methods which
// perform the task of object creation.
virtual CDataComponent* MakeDataComp()
{
return new CDataComponent();
}
virtual CUIComponent* MakeUIComp()
{
return new CUIComponent();
}
virtual CToolBarComponent* MakeToolBarComp(UINT nID)
{
return new CToolBarComponent(nID);
}
CUITemplate* CreateUI()
{
CDataComponent* pData = MakeDataComp();
CUIComponent* pUI = MakeUIComp();
CToolBarComponent* pTooBar1 = MakeToolBarComp(ID_STANDARD);
CToolBarComponent* pTooBar2 = MakeToolBarComp(ID_CUSTOM);
pTooBar2->AddDropDownButton();
pTooBar2->AddComboBox();
pUI->AddToolBar(pTooBar1);
pUI->AddToolBar(pTooBar2);
return new CUITemplate(pData, pUI);
}
};
struct pa_diddle { virtual ~pa_diddle(); virtual void diddle() = 0; };
struct bo_diddle : pa_diddle { void diddle() { bo(); }};
struct lee_diddle : pa_diddle { void diddle() { lee(); }};
struct diddle_builder
{
enum name { BO, LEE };
pa_diddle * build_diddle(name n)
{
switch(n)
{
case BO: return new bo_diddle();
case LEE: return new lee_diddle();
}
}
};
Crud, ich habe total vermisst, dass Sie für Factory-Methode, nicht abstrakte Fabrik suchen. Das ist, was ich gerade ein Beispiel gegeben habe.
Hier Factory Method:
struct some_abstraction { ... };
struct some_class
{
... functions and stuff ...
struct something_only_some_class_knows_about : some_abstraction {};
some_abstraction* create_whatnot() const { return new something....about; }
};
+1 für kompakte und umfassende sein ... und für structs verwendet;) – Frunsi
Ich denke, dass die Schlüsselidee in diesem Code wird betont, nicht wirklich. Das Problem ist, dass derjenige, der das Objekt erstellt, immer noch die Sichtbarkeit aller möglichen Klassen (zumindest ihren "enum-code") haben muss und somit das "if" selbst machen könnte. Viel idiomatischer ist IMO, wenn 'diddle_builder' stattdessen über einen Vektor von Konstruktorfunktionen iteriert und wenn der Klassenselektor eine allgemeine Zeichenkette oder Ganzzahl ist, so dass ich Code schreiben kann, der Objekte von Klassen erzeugt, die in keiner Form bekannt sind Ich weiß nicht einmal zur Kompilierzeit, wie viele mögliche Klassen es gibt). – 6502
@ 6502 - yeah, sure ... aber du schreibst es: p Das ist ein bisschen mehr Arbeit als ich im Moment bezahlt werde. –
Direkt Beispiel von GoF: (sorry für Ausführlichkeit)
/*
*/
class Product {};
#ifdef Implementation1
class MyProduct : public Product {};
class YourProduct : public Product {};
class TheirProduct : public Product {};
typedef int ProductId;
const int MINE = 1;
const int YOURS = 2;
const int THEIRS = 2;
/*
*/
class Creator {
public:
virtual Product* Create(ProductId);
};
/*
*/
Product* Creator::Create (ProductId id) {
if (id == MINE) return new MyProduct;
if (id == YOURS) return new YourProduct;
// repeat for remaining products...
return 0;
}
/*
*/
class MyCreator : public Creator {
public:
virtual Product* Create(ProductId);
};
/*
*/
Product* MyCreator::Create (ProductId id) {
if (id == YOURS) return new MyProduct;
if (id == MINE) return new YourProduct;
// N.B.: switched YOURS and MINE
if (id == THEIRS) return new TheirProduct;
return Creator::Create(id); // called if all others fail
}
/*
*/
#endif
#ifdef Implementation2
/*
*/
class Creator {
public:
Product* GetProduct();
protected:
virtual Product* CreateProduct();
private:
Product* _product;
};
/*
*/
Product* Creator::GetProduct() {
if (_product == 0) {
_product = CreateProduct();
}
return _product;
}
/*
*/
#endif
#ifdef Implementation3
/*
*/
class Creator {
public:
virtual Product* CreateProduct() = 0;
};
/*
*/
template <class TheProduct>
class StandardCreator: public Creator {
public:
virtual Product* CreateProduct();
};
/*
*/
template <class TheProduct>
Product* StandardCreator<TheProduct>::CreateProduct() {
return new TheProduct;
}
/*
*/
class MyProduct : public Product {
public:
MyProduct();
// ...
};
StandardCreator<MyProduct> myCreator;
/*
*/
#endif
/*
*/
#include "C++/MazeParts.H"
/*
*/
class MazeGame {
public:
Maze* CreateMaze();
/*
*/
// factory methods:
/*
*/
virtual Maze* MakeMaze() const
{ return new Maze; }
virtual Room* MakeRoom(int n) const
{ return new Room(n); }
virtual Wall* MakeWall() const
{ return new Wall; }
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return new Door(r1, r2); }
};
/*
*/
Maze* MazeGame::CreateMaze() {
Maze* aMaze = MakeMaze();
/*
*/
Room* r1 = MakeRoom(1);
Room* r2 = MakeRoom(2);
Door* theDoor = MakeDoor(r1, r2);
/*
*/
aMaze->AddRoom(r1);
aMaze->AddRoom(r2);
/*
*/
r1->SetSide(North, MakeWall());
r1->SetSide(East, theDoor);
r1->SetSide(South, MakeWall());
r1->SetSide(West, MakeWall());
/*
*/
r2->SetSide(North, MakeWall());
r2->SetSide(East, MakeWall());
r2->SetSide(South, MakeWall());
r2->SetSide(West, theDoor);
/*
*/
return aMaze;
}
/*
*/
class BombedMazeGame : public MazeGame {
public:
BombedMazeGame();
/*
*/
virtual Wall* MakeWall() const
{ return new BombedWall; }
/*
*/
virtual Room* MakeRoom(int n) const
{ return new RoomWithABomb(n); }
};
/*
*/
class EnchantedMazeGame : public MazeGame {
public:
EnchantedMazeGame();
/*
*/
virtual Room* MakeRoom(int n) const
{ return new EnchantedRoom(n, CastSpell()); }
/*
*/
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return new DoorNeedingSpell(r1, r2); }
protected:
Spell* CastSpell() const;
};
/*
*/
================== ================================================= =
//Mazeparts.h #included file
#ifndef MazeParts_H
#define MazeParts_H
#include "defs.H"
enum Direction { North, East, South, West };
#ifndef MapSite_H
#define MapSite_H
class MapSite {
public:
virtual void Enter() = 0;
};
#endif
#ifndef _H
#define _H
class Room : public MapSite {
public:
Room(int = 0);
Room(const Room&);
virtual Room* Clone() const;
void InitializeRoomNo(int);
MapSite* GetSide(Direction);
void SetSide(Direction, MapSite*);
virtual void Enter();
private:
MapSite* _sides[4];
int _roomNumber;
};
#endif
#ifndef Wall_H
#define Wall_H
class Wall : public MapSite {
public:
Wall();
Wall(const Wall&);
virtual Wall* Clone() const;
virtual void Enter();
};
#endif
#ifndef Door_H
#define Door_H
class Door : public MapSite {
public:
Door(Room* = 0, Room* = 0);
Door(const Room&);
virtual Door* Clone() const;
void Initialize(Room*, Room*);
virtual void Enter();
Room* OtherSideFrom(Room*);
private:
Room* _room1;
Room* _room2;
bool _isOpen;
};
#endif
#ifndef Maze_H
#define Maze_H
class Maze {
public:
Maze();
Maze(const Maze&);
Room* RoomNo(int);
void AddRoom(Room*);
virtual Maze* Clone() const;
private:
// ...
};
#endif
#ifndef BombedWall_H
#define BombedWall_H
class BombedWall : public Wall {
public:
BombedWall(bool bombed = false);
BombedWall(const BombedWall&);
virtual Wall* Clone() const;
void Intialize(bool);
virtual void Enter();
private:
bool _bomb;
};
#endif
#ifndef RoomWithABomb_H
#define RoomWithABomb_H
class RoomWithABomb: public Room {
public:
RoomWithABomb(int = 0, bool bombed = false);
RoomWithABomb(const RoomWithABomb&);
bool HasBomb();
private:
bool _bomb;
};
#endif
#ifndef EnchantedRoom_H
#define EnchantedRoom_H
class Spell;
class EnchantedRoom : public Room {
public:
EnchantedRoom(int, Spell* = 0);
EnchantedRoom(const EnchantedRoom&);
bool HasSpell();
Spell PickUpSpell();
private:
Spell* _spell;
};
#endif
#ifndef DoorNeedingSpell_H
#define DoorNeedingSpell_H
class DoorNeedingSpell : public Door {
public:
DoorNeedingSpell(Room*, Room*);
DoorNeedingSpell(const DoorNeedingSpell&);
bool TrySpell(Spell);
};
#endif
#endif
Vielleicht wäre ein Link eine bessere Idee gewesen? Gott hilf irgendjemandem, vorbei zu waten, um die Antworten unten zu sehen ... –
Ich habe versucht, den FTP-Link online zu öffnen, von wo ich diesen Code heruntergeladen habe, als ich gof book gekauft habe, aber dieser ftp-Link funktioniert nicht mehr. Also habe ich es hier kopiert. Nochmals, Entschuldigung dafür. – Viren
- 1. Verwendung `` ++ in Muster
- 2. Thread und Muster Verwendung
- 3. Entsorgen Muster Verwendung
- 4. Wahl geeignete Methode Muster unter Verwendung passender in C#
- 5. Repository-Muster in C#
- 6. Zellenvorlage mit Hyperlink-Verwendung in MVVM-Muster
- 7. Directory.GetFiles() Muster übereinstimmen in C#
- 8. C#: Gibt es ein sauberes Muster zum Finden des richtigen Objekts in Verbindung mit der Verwendung?
- 9. Implementieren Besucher Muster in C#
- 10. Muster für die Verwendung von EntityFramework?
- 11. C# Desktop-Muster ändern
- 12. Objective-C Singleton-Muster in iOS 5+
- 13. Wie zu implementieren Observer-Muster in C++
- 14. C#, Muster - viele Bedingungen
- 15. C# - Singleton Muster
- 16. C# Producer/Consumer Muster
- 17. Singleton Muster für C#
- 18. C# Regex.Replace Muster benötigt
- 19. Die Verwendung der freien Funktion in c
- 20. C++ Verwendung der Klasse Klassenname;
- 21. Verwendung der abstrakten Decorator-Klasse im Decorator-Muster
- 22. Strategie Muster mit verschiedenen Parametern in der Schnittstelle (C#)
- 23. Muster für die Spezialisierung der generischen Klasse in C#?
- 24. Verwendung einer Nachschlagetabelle für Regex-Muster
- 25. C# RegEx: Ignoriere Fall ... im Muster?
- 26. #define Verwendung in C/C++
- 27. ng-Muster zur Verwendung Regex von Winkelkonstanten
- 28. C# - Verwendung der Variablen vor der Initialisierung
- 29. Verwendung list.ForEach in C#
- 30. Array-Verwendung in C
Warum bestehen Leute darauf, ein "C" als Präfix für eine Klasse zu verwenden. Warum ist es notwendig zu vermitteln, dass der Typ eine Klasse ist? sehr scheußlich - wenn auch nicht so schlecht wie die ungarische Notation. –
IMHO, es ist mehr ein "Erbauer" als eine Fabrikmethode. –