C++程式設計思想 第2卷 第10章 設計模式 工廠模式:封裝物件的建立 多型工廠
阿新 • • 發佈:2018-12-09
強調工廠方法的理由是 可以使不同型別的工廠派生自基本型別的工廠 工廠方法模式事實上是多型工廠模式的一個特例
//: C10:ShapeFactory2.cpp // From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison. // (c) 1995-2004 MindView, Inc. All Rights Reserved. // See source code use permissions stated in the file 'License.txt', // distributed with the code package available at www.MindView.net. // Polymorphic Factory Methods. #include <iostream> #include <map> #include <string> #include <vector> #include <stdexcept> #include <cstddef> #include "../purge.h" using namespace std; class Shape { public: virtual void draw() = 0; virtual void erase() = 0; virtual ~Shape() {} }; class ShapeFactory { virtual Shape* create() = 0; static map<string, ShapeFactory*> factories; public: virtual ~ShapeFactory() {} friend class ShapeFactoryInitializer; class BadShapeCreation : public logic_error { public: BadShapeCreation(string type) : logic_error("Cannot create type " + type) {} }; static Shape* createShape(const string& id) throw(BadShapeCreation) { if(factories.find(id) != factories.end()) return factories[id]->create(); else throw BadShapeCreation(id); } }; // Define the static object: map<string, ShapeFactory*> ShapeFactory::factories; class Circle : public Shape { Circle() {} // Private constructor friend class ShapeFactoryInitializer; class Factory; friend class Factory; class Factory : public ShapeFactory { public: Shape* create() { return new Circle; } friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Circle::draw" << endl; } void erase() { cout << "Circle::erase" << endl; } ~Circle() { cout << "Circle::~Circle" << endl; } }; class Square : public Shape { Square() {} friend class ShapeFactoryInitializer; class Factory; friend class Factory; class Factory : public ShapeFactory { public: Shape* create() { return new Square; } friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Square::draw" << endl; } void erase() { cout << "Square::erase" << endl; } ~Square() { cout << "Square::~Square" << endl; } }; // Singleton to initialize the ShapeFactory: class ShapeFactoryInitializer { static ShapeFactoryInitializer si; ShapeFactoryInitializer() { ShapeFactory::factories["Circle"]= new Circle::Factory; ShapeFactory::factories["Square"]= new Square::Factory; } ~ShapeFactoryInitializer() { map<string, ShapeFactory*>::iterator it = ShapeFactory::factories.begin(); while(it != ShapeFactory::factories.end()) delete it++->second; } }; // Static member definition: ShapeFactoryInitializer ShapeFactoryInitializer::si; char* sl[] = { "Circle", "Square", "Square", "Circle", "Circle", "Circle", "Square" }; int main() { vector<Shape*> shapes; try { for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++) shapes.push_back(ShapeFactory::createShape(sl[i])); } catch(ShapeFactory::BadShapeCreation e) { cout << e.what() << endl; return EXIT_FAILURE; } for(size_t i = 0; i < shapes.size(); i++) { shapes[i]->draw(); shapes[i]->erase(); } purge(shapes); getchar(); } ///:~
輸出 Circle::draw Circle::erase Square::draw Square::erase Square::draw Square::erase Circle::draw Circle::erase Circle::draw Circle::erase Circle::draw Circle::erase Square::draw Square::erase Circle::~Circle Square::~Square Square::~Square Circle::~Circle Circle::~Circle Circle::~Circle Square::~Square
工廠方法作為virtual create()出現在它自己的ShapeFactory類中 這是一個私有成員函式 意味著不能直接呼叫它 但可以被覆蓋