强制一个通用的工厂来创建对象,而不允许将创建对象的代码散布于整个系统。如果程序中所有需要创建对象的代码都转到这个工厂执行,那么在增加新对象时所要做的全部工作就是只需修改工厂。
//: C10:ShapeFactory1.cpp
#include <iostream>
#include <stdexcept>
#include <cstddef>
#include <string>
#include <vector>
#include "../purge.h"
using namespace std;
class Shape {
public:
virtual void draw() = 0;
virtual void erase() = 0;
virtual ~Shape() {}
class BadShapeCreation : public logic_error {
public:
BadShapeCreation(string type)
: logic_error("Cannot create type " + type) {}
};
static Shape* factory(const string& type)
throw(BadShapeCreation);
};
class Circle : public Shape {
Circle() {} // Private constructor
friend class Shape;
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 Shape;
public:
void draw() { cout << "Square::draw" << endl; }
void erase() { cout << "Square::erase" << endl; }
~Square() { cout << "Square::~Square" << endl; }
};
Shape* Shape::factory(const string& type)
throw(Shape::BadShapeCreation) {
if(type == "Circle") return new Circle;
if(type == "Square") return new Square;
throw BadShapeCreation(type);
}
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(Shape::factory(sl[i]));
} catch(Shape::BadShapeCreation e) {
cout << e.what() << endl;
purge(shapes);
return EXIT_FAILURE;
}
for(size_t i = 0; i < shapes.size(); i++) {
shapes[i]->draw();
shapes[i]->erase();
}
purge(shapes);
} ///:~
函数factory()允许以一个参数来决定创建何种类型的Shape。在这里,参数类型为string,
也可以是任何数据集。在添加新的Shape类型时,函数factory()是当前系统中惟一需要修改
的代码。(对象的初始化数据大概也可以由系统外获得,而不必像本例中那样来自硬编码数
组。)
这样的设计还有另外一个重要的含义--基类Shape现在必须了解每个派生类的细节--这
是面向对象设计试图避免的一个性质。对于结构框架或者任何类库来说都应该支持扩充,但
这样一来,系统很快就会变得笨拙,因为一旦新类型被加到这种层次结构中,基类就必须更
新。可以用下面的多态工厂(polymorphic factory)来避免这种循环依赖。
//: C10:ShapeFactory2.cpp
// 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);
} ///:~
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
现在,工厂方法模式作为virtual create()出现在它自己的ShapeFactory类中。这是一个私
有成员函数,意味着不能直接调用它,但可认被覆盖。Shape的子类必须创建各自的ShapeFactory
子类,并且覆盖成员函数create()以创建其自身类型的对象。这些工厂得私有的,只能被主
工厂方法模式访问。采用这种方法,所有客户代码都必须通过工厂方法模式创建对象。
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
抽象工厂模式看卢来和前面看到的工厂方法很相似,只是它使用若干工厂方法模式。每个工厂方法模式创建一个不同类型的对象。当创建一个工厂对象时,要决定将如何使用由那个工厂创建的所有对象。
//: C10:AbstractFactory.cpp
// A gaming environment.
#include <iostream>
using namespace std;
class Obstacle {
public:
virtual void action() = 0;
};
class Player {
public:
virtual void interactWith(Obstacle*) = 0;
};
class Kitty: public Player {
virtual void interactWith(Obstacle* ob) {
cout << "Kitty has encountered a ";
ob->action();
}
};
class KungFuGuy: public Player {
virtual void interactWith(Obstacle* ob) {
cout << "KungFuGuy now battles against a ";
ob->action();
}
};
class Puzzle: public Obstacle {
public:
void action() { cout << "Puzzle" << endl; }
};
class NastyWeapon: public Obstacle {
public:
void action() { cout << "NastyWeapon" << endl; }
};
// The abstract factory:
class GameElementFactory {
public:
virtual Player* makePlayer() = 0;
virtual Obstacle* makeObstacle() = 0;
};
// Concrete factories:
class KittiesAndPuzzles : public GameElementFactory {
public:
virtual Player* makePlayer() { return new Kitty; }
virtual Obstacle* makeObstacle() { return new Puzzle; }
};
// Other Concrete factories:
class KillAndDismember : public GameElementFactory {
public:
virtual Player* makePlayer() { return new KungFuGuy; }
virtual Obstacle* makeObstacle() {return new NastyWeapon;}
};
class GameEnvironment {
GameElementFactory* gef;//环境
Player* p; //动作
Obstacle* ob; //角色
public:
GameEnvironment(GameElementFactory* factory)
: gef(factory), p(factory->makePlayer()),
ob(factory->makeObstacle()) {}
void play() { p->interactWith(ob); }
~GameEnvironment() {
delete p;
delete ob;
delete gef;
}
};
int main() {
GameEnvironment
g1(new KittiesAndPuzzles),
g2(new KillAndDismember);
g1.play();
g2.play();
}
/* Output:
Kitty has encountered a Puzzle
KungFuGuy now battles against a NastyWeapon */ ///:~
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
在此环境中,Player对象与Obstrcle对象交互,但是Player和Obstacle类型依赖具体的游戏。可以选择特定的GameElementFactory来决定游戏的类型,然后GameEnvironment控制游戏的设置和进行。在本例中,游戏的设置和进行很简单,但是那些动作(初始条件和状态变化在很大程度上决定了游戏的结果。在这里,GameEnvironment不是设计成继承的,即使这样做可能是有意义的。
相关推荐
本文以实例形式较为详细的介绍了PHP设计...2、工厂方法模式(Factory Method)又叫做 多态性工厂模式(Polymorphic Factory) 3、抽象工厂模式(Abstract Factory)又叫做 工具箱模式(ToolKit) 二、配图分析: 三、代码实例
Polymorphic Time Systems for Estimating Program Complexity
工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。 工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实 际创建工作推迟到子类中。
polymorphic virus analysis,一篇病毒分析的文章。
壳程序Anskya Polymorphic Packer 源码
关于类型推断理论的论文,主要可用于scala这种带类型推断的静态语言。
DAQNavi Polymorphic VI包含的VI如下所示: DAQNavi Create Channel VI DAQNavi Read DAQNavi Write DAQNavi Timing DAQNavi Trigger DAQNavi Start Task DAQNavi Stop Task DAQNavi Clear Task DAQNavi Is ...
polymorphic.zip
资源来自pypi官网,解压后可用。 资源全名:django_polymorphic_tree-2.1-py3-none-any.whl
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂...(2)工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtua
采用基于模式的特征提取算法,通过对多个可疑Polymorphic蠕虫流量进行序列比对,自动提取它们的最长公共子序列,结果用两种形式的向量表示;并采用相似度度量的检测方法,利用已提取的特征向量,判别新到来的...
建议将类模板polymorphic_value添加到C ++标准库中。 类模板polymorphic_value赋予免费存储分配的对象类似值的语义。 polymorphic_value可以保存从T公开派生的类的对象,并且复制polymorphic_value将复制派生类型...
工厂方法(Factory Method)模式又称为虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,属于类的创建型模式。在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成...
The broad range of concepts includes fundamental data types such as sums and products, polymorphic and abstract types, dynamic typing, dynamic dispatch, subtyping and refinement types, symbols and ...
c语言实现C++多态之诸葛亮的锦囊妙计,通过函数回调实现多态思想,具体可重写与函数指针类型匹配的函数,实现各自具体的功能,调用时直接传惨。
资源来自pypi官网。 资源全名:django-polymorphic-1.1.tar.gz
采用基于模式的特征提取算法NLA(Normalized Local Alignment),通过对多个可疑Polymorphic蠕虫流量进行序列比对,自动提取高相似度公共子序列,以向量的形式构造蠕虫特征。实验结果表明该算法在误报率和漏报率方面...
概述django-rest-polymorphic允许您轻松定义使用django-polymorphic库创建的继承模型的序列化器。安装使用pip安装: $ pip install django-rest-polymorphic用法定义多态模型: # models.pyfrom django . db import ...
Laravel开发-improved-polymorphic-eloquent-builder 由于雄辩无法确定要检索的正确模型,尝试使用具有标准雄辩多态关系的wherehas查询将失败。“改进的多态雄辩生成器”是一个类,它将内置的雄辩生成器类扩展到...