类中存在纯虚函数,为抽象类,不能实例化。
类中的静态方法可以通过对象或类名调用。
如果,我们将抽象类,或者普通类的构造函数设置为保护态,那么就相当于无法通过外部的行为构造对象,只能通过不依赖this的静态方法调用(静态方法调用构造函数)。
简单工厂模式: 当我们需要什么,只需要传入正确的参数,就可以得到对应的对象。我们无需知道其创建细节。
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
模式组成
组成(角色) | 关系 | 作用 |
---|---|---|
抽象产品(Product) | 具体产品的父类 | 描述产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类;工厂类创建的目标类 | 描述生产的具体产品 |
工厂(Creator) | 被外界调用 | 根据传入不同参数从而创建不同具体产品类的实例 |
作者:Carson_Ho
链接:https://www.jianshu.com/p/e55fbddc071c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码示例:
#include <iostream>
#include <stdexcept>
#include <cstddef>
#include <string>
#include<map>
using namespace std;
// 逻辑错误是由于程序内部逻辑而导致的错误
class BadShapeCreation : public logic_error
{
public:
BadShapeCreation(string type)
: logic_error("Cannot create type " + type) {}
};
/* 抽象商品类 */
class Shape
{
public:
virtual void draw() = 0;
virtual void erase() = 0;
virtual ~Shape() {}
static Shape* factory(const string& type);
};
class Circle : public Shape
{
Circle() { cout << "Circle Construct" << endl; } // Private constructor
friend class Shape;
public:
void draw()
{
cout << "Circle::draw" << endl;
}
void erase()
{
cout << "Circle::erase" << endl;
}
~Circle()
{
cout << "Circle destructor" << endl;
}
};
class Square : public Shape
{
Square() { cout << "Square Construct" << endl; }
friend class Shape;
public:
void draw()
{
cout << "Square::draw" << endl;
}
void erase()
{
cout << "Square::erase" << endl;
}
~Square()
{
cout << "Square destructor" << endl;
}
};
/* 工厂类 */
Shape* Shape::factory(const string& type) throw(BadShapeCreation)
{
if (type == "Circle") return new Circle;
if (type == "Square") return new Square;
throw BadShapeCreation(type);
}
class ShapeFactory
{ // 使用智能指针,自动管理内存释放
std::map<string, shared_ptr<Shape> > shapes;
public:
ShapeFactory()
{
// 读取配置文件中“菜单”,决定工厂中预先创建何种商品。这样在商品改动时,我们无需改动代码
// 或这构造中传入“菜单”,但这样在“菜单”过多时较为麻烦。
shapes.insert(std::pair<string, shared_ptr<Shape> >("Circle", Shape::factory("Circle")));
shapes.insert(std::pair<string, shared_ptr<Shape> >("Square", Shape::factory("Square")));
}
~ShapeFactory()
{}
shared_ptr<Shape> GetShape(const string str)
{
return shapes[str];
}
};
int main()
{
unique_ptr<ShapeFactory> psf(new ShapeFactory());
auto pcir = psf->GetShape("Circle"); // 构建圆形
pcir->draw();
pcir->erase();
auto psqa = psf->GetShape("Square"); // 构建正方形
psqa->draw();
psqa->erase();
auto psqa2 = psf->GetShape("Square"); // 构建正方形
psqa2->draw();
psqa2->erase();
return 0;
}
工厂模式:
需要多个工厂,与简单工厂模式不同的是,工厂模式中产品的构建方式不唯一。在简单工厂模式中,所有产品使用一种构建方式,故一个工厂足以。具体区别如下:
简单工厂:所有产品继承自抽象产品,由抽象类中的方法构建产品。所有产品统一由一个工厂完成生产。
工厂模式:给每一种产品一个工厂,用于生产产品。
抽象产品类–>具体产品类,
抽象工厂类–>具体产品工厂类,生产具体产品
设计步骤:
步骤 1: 创建抽象工厂类,定义具体工厂的公共接口;
步骤 2: 创建抽象产品类 ,定义具体产品的公共接口;
步骤 3: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤 4: 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤 5: 外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例。
比如下面这个例子,比亚迪汽车和吉利汽车的生产工序是不同的,需要两种不同的工厂进行加工。
#include <iostream>
using namespace std;
class Car//车类
{
public:
virtual void Show(void) = 0;
virtual ~Car() {}
};
class BydCar : public Car //比亚迪汽车
{
public:
BydCar() { cout << "Byd::Byd()" << endl; }
~BydCar() { }
virtual void Show(void)
{
cout << "BYD auto" << endl;
}
};
class GeelyCar : public Car // 吉利汽车
{
public:
GeelyCar() { cout << "Geely::Geely()" << endl; }
~GeelyCar() {}
virtual void Show(void)
{
cout << "GEELY auto" << endl;
}
};
class Factory//车厂
{
public:
virtual Car* createCar(void) = 0;
};
class BydFactory : public Factory
{
public: // 省略部分操作..
virtual Car* createCar(void) { return (new BydCar()); }
};
class GeelyFactory : public Factory
{
public: // 省略部分操作..
virtual Car* createCar(void) { return (new GeelyCar()); }
};
int main()
{
Factory* factory = new BydFactory();
Car* bydCar = factory->createCar();
factory = new GeelyFactory();
Car* GeelyCar = factory->createCar();
delete factory;
delete bydCar;
delete GeelyCar;
return 0;
}
如果上面的例子不够浅显的话,就那生成日志之一功能来作为例子。日志可分为普通的文件日志,或是数据库的日志,而记录数据库的日志需要我们进行连接数据库,查询数据库等操作; 而记录文件日志的步骤与数据库的又不同,比如我们调用系统日志。总之两种同属日志文件,而具体操作不同,因此我们需要两个工厂分别生产他们的对象。
注: 通过智能指针管理内存。