2011-01-14 6 views

Antwort

1

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); 
    } 
}; 
+1

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. –

+0

IMHO, es ist mehr ein "Erbauer" als eine Fabrikmethode. –

1
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; } 
}; 
+0

+1 für kompakte und umfassende sein ... und für structs verwendet;) – Frunsi

+0

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

+0

@ 6502 - yeah, sure ... aber du schreibst es: p Das ist ein bisschen mehr Arbeit als ich im Moment bezahlt werde. –

0

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 
+0

Vielleicht wäre ein Link eine bessere Idee gewesen? Gott hilf irgendjemandem, vorbei zu waten, um die Antworten unten zu sehen ... –

+0

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