2011-01-14 3 views

ответ

1

Мне нравится то, что делает учит Codeproject:

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

Почему люди настаивают на использовании «С» в качестве префикса для класса. Почему необходимо передать тот факт, что тип является классом? очень asinine - хотя и не так плохо, как венгерская нотация. –

+0

IMHO, это скорее «строитель», чем заводский метод. –

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, я полностью пропустил то, что вы искали 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 за то, что компактный и всеобъемлющий ... и для использования структур;) – Frunsi

+0

Я думаю, что в этом коде ключевая идея не очень подчеркнуты. Проблема в том, что тот, кто строит объект, все же должен обладать видимостью всех возможных классов (по крайней мере, их «enum-code»), и поэтому мог бы сам «if». Гораздо более идиоматичным является ИМО, если 'diddle_builder' вместо этого выполняет итерацию над вектором функций конструктора, и если селектор классов является общей строкой или целым числом, чтобы я мог писать код, который создает объекты классов, которые не известны ни в какой форме, время компиляции (например, Во время компиляции я даже не знаю, сколько там классов). – 6502

+0

@ 6502 - да, конечно ... но вы пишете это: p Это немного больше работы, чем мне платят в данный момент. –

0

Прямой пример из GoF: (извините за многословие)

/* 
*/ 
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

Может быть, ссылка была бы лучшей идеей? Боже, помогите кому-нибудь пройти мимо этого, чтобы увидеть ответы ниже .... –

+0

Я попытался открыть ftp-ссылку онлайн, откуда я загрузил этот код, когда купил книгу gof, но эта ftp-ссылка больше не работает. Поэтому я скопировал его здесь. Опять же, извиняюсь за это. – Viren

Смежные вопросы