通过一个加工厂,在这个工厂中添加对应材料,我们就可以得到想要的东西,在程序设计中,这种模式就叫做工厂模式,工厂生成出的产品就是某个类的实例,也就是对象。
关于工厂模式一共有三种,分别是:简单工厂模式、工厂模式、抽象工厂模式。
比如说你要生产一些物品,生产的方法都是一样的只是原材料不同。你可以设计一个基类,提供生产方法。然后将要生产的对象材料加入到生产类中即可。后面可以再定义一个对象工厂类,用来创建对应材料。
创建一个新的类, 可以将这个类称之为工厂类。对于简单工厂模式来说,需要的工厂类只有一个。工厂类中添加一个公共的成员函数,通过这个函数来创建我们需要的对象,通过这个对象调用工厂函数,这样就可以生产出一个指定类型的实例对象了。这里可以使用c++中的多态来完成。
例如:先定义一个基类,将其方法定义为虚函数。
- class Product
- {
- public:
- Product()
- {
- ;
- }
- virtual void produce()
- {
- cout << "进行生产" << endl;
- }
- virtual ~Product()
- {
- cout << "资源释放" << endl;
- }
- };
定义要实例化的对象
- class Milk :public Product
- {
- public:
- void produce()
- {
- cout << "生产了牛奶" << endl;
- }
- ~Milk()
- {
- cout << "delete Milk" << endl;
- }
- };
-
- class Apple :public Product
- {
- public:
- void product()
- {
- cout << "生产了apple" << endl;
- }
- ~Apple()
- {
- cout << "delete apple" << endl;
- }
- };
定义物品工厂类,用来生产对应材料
- enum class Type :char { milk,apple };
- class Factory
- {
- public:
- Product* p = nullptr;
- Product* create(Type T)
- {
- switch (T)
- {
- case Type::milk:
- p = new Milk;
- break;
- case Type::apple:
- p = new Apple;
- break;
- default:
- break;
- }
- return p;
- }
- };
- int main()
- {
-
- Factory* f = new Factory;
- Product* p = f->create(Type::milk);//需要生产材料,就对其参数进行修改
- p->produce();
- delete p;
- return 0;
- }
如果要可以生成更多种类的物品,需要添加更多的物品对象,同时还要在工厂函数的switch语句中添加更多的case,很明显这违背了封闭原则。
简单工厂模式是只有一个工厂类,而工厂模式是有很多的工厂类。
代码:
- class Product
- {
- public:
-
- virtual void produce()
- {
- cout << "进行生产" << endl;
- }
- virtual ~Product()
- {
- cout << "资源释放" << endl;
- }
- };
-
- class Milkpro :public Product
- {
- public:
-
- void produce()
- {
- cout << "生产了牛奶" << endl;
- }
- ~Milkpro()
- {
- cout << "delete Milk" << endl;
- }
- };
-
- class Applepro :public Product
- {
- public:
-
- void product()
- {
- cout << "生产了apple" << endl;
- }
- ~Applepro()
- {
- cout << "delete apple" << endl;
- }
- };
-
- class Factory//并没有在这个类中直接生产材料,而是定义为抽象类
- {
- public:
- virtual Product* creat() = 0;
- virtual ~Factory()
- {
- ;
- }
- };
-
- class Milk :public Factory
- {
- public:
-
- Product* creat()
- {
- return new Milkpro;
- }
- ~Milk()
- {
- cout << "delete Milk" << endl;
- }
- };
- class Apple :public Factory
- {
- public:
- Product* creat()
- {
- return new Applepro;
- }
- ~Apple()
- {
- cout << "delete Apple" << endl;
- }
- };
- int main()
- {
- Factory* f = new Milk;
- Product* p= f->creat();
- p->produce();
- delete p;
- return 0;
- }
假如要生产一艘船,该船的组成为:
船体,船的动力系统,船中配备的武器。
船体的选择:木材 合金
动力系统的选择:人力驱动,核反应驱动
武器的选择:枪,自动机关炮
这样一共就有8种选则。
船体,因为船体材料的这个属性是可变的,所以还需要给它提供一个抽象类,在这个抽象类的子类中就可以去更换不同的船体材料。
- class ShipBody
- {
- public:
- virtual string getShipBody() = 0;
- virtual ~ShipBody() {}
- };
-
- class WoodBody : public ShipBody
- {
- public:
- string getShipBody() override
- {
- return string("用<木材>制作轮船船体...");
- }
- };
-
- class MetalBody : public ShipBody
- {
- public:
- string getShipBody() override
- {
- return string("用<合金>制作轮船船体...");
- }
- };
动力系统与武器也是一样:
- // 动力
- class Engine
- {
- public:
- virtual string getEngine() = 0;
- virtual ~Engine() {}
- };
-
- class Human : public Engine
- {
- public:
- string getEngine() override
- {
- return string("使用<人力驱动>...");
- }
- };
- class Nuclear : public Engine
- {
- public:
- string getEngine() override
- {
- return string("使用<核能驱动>...");
- }
- };
-
- // 武器
- class Weapon
- {
- public:
- virtual string getWeapon() = 0;
- virtual ~Weapon() {}
- };
-
- class Gun : public Weapon
- {
- public:
- string getWeapon() override
- {
- return string("配备的武器是<枪>");
- }
- };
-
- class Cannon : public Weapon
- {
- public:
- string getWeapon() override
- {
- return string("配备的武器是<自动机关炮>");
- }
- };
一首船需要3个组成部分,这里用3个变量来表示:
- class Ship
- {
- public:
- Ship(ShipBody* body, Weapon* weapon, Engine* engine) :
- m_body(body), m_weapon(weapon), m_engine(engine)
- {
- }
- string getProperty()
- {
- // 这也是多态实现,获取对应船组成部分的材料
- string info = m_body->getShipBody() + m_weapon->getWeapon() + m_engine->getEngine();
- return info;
- }
- ~Ship()
- {
- delete m_body;
- delete m_engine;
- delete m_weapon;
- }
- private:
- ShipBody* m_body = nullptr;
- Weapon* m_weapon = nullptr;
- Engine* m_engine = nullptr;
- };
工厂类与上面一样,不直接进行提供船部件,而是定义为抽象类,让子类去提供船的部件。
- / 工厂类
- class AbstractFactory
- {
- public:
- virtual Ship* createShip() = 0;
- virtual ~AbstractFactory() {}
- };
-
- class BasicFactory : public AbstractFactory//定义木头,枪,人力的船
- {
- public:
- Ship* createShip() override
- {
- Ship* ship = new Ship(new WoodBody, new Gun, new Human);
- cout << "<基础型>战船生产完毕, 可以下水啦..." << endl;
- return ship;
- }
- };
结果:
- int main()
- {
- AbstractFactory* factroy = new BasicFactory;
- Ship* ship = factroy->createShip();
- cout << ship->getProperty();
- delete ship;
- delete factroy;
- return 0;
- }
对比:
一个简单的例子:交叉路口的红绿灯。过往的车辆就是观察者或则是订阅者,信号灯就是消息的发布者。当车辆到了该路口,车辆就会观测路灯,当路灯为红灯时,车辆即可通行。当车辆远离该路口时,车辆就不需要观察路灯的信号了。
其他例子:购买的商品被送到菜鸟驿站,会收到驿站发送的提示信息。
这里以报刊为例,报刊可以发布多种类型的消息给不同的人。
发布者,需要满足以下的需求:
发布者未必是一种类型的,不同的发布者可以发布不同种类的消息。先创建出一个发布者的抽象类。
class Observer;//订阅者抽象类
class NewsAgency//发布者抽象类
{
public:
void attach(Observer* ob)
{
m_list.push_back(ob);//增加订阅者
}
void deatch(Observer* ob)
{
m_list.remove(ob);//删除订阅者
}
virtual void notify(string msg) = 0;//通知
virtual ~NewsAgency() {};
protected:
listm_list; // 订阅者列表
};class News_A :public NewsAgency
{
public:
void notify(string msg) override
{
cout << "这是NewA新闻报刊" << endl;
for (auto ch : m_list)
{
ch->update(msg);
}
}
};
class News_B :public NewsAgency
{
public:
void notify(string msg) override
{
cout << "这是NewB新闻报刊" << endl;
for (auto ch : m_list)
{
ch->update(msg);
}
}
};
观察者也未必只是一种对象,给所有的观察者定义一个抽象的基类。
// 抽象的订阅者类
class Observer
{
public://通过构造函数给观察者类提供一个信息的发布者
Observer(string name, NewsAgency* news) :m_name(name), m_news(news)
{
m_news->attach(this);//发布者对象将观察者对象存储了起来,可以收到发布的消息
}
void unsubscribe()
{
m_news->deatch(this);//订阅者取消订阅
}
virtual void update(string msg) = 0;
virtual ~Observer() {}
protected:
string m_name;
NewsAgency* m_news;
};class Observer_A : public Observer//订阅者A
{
public:
using Observer::Observer;
void update(string msg) override
{
cout << "订阅者A收到新消息: " << msg << endl;
}
};class Observer_B : public Observer//订阅者B
{
public:
using Observer::Observer;
void update(string msg) override
{
cout << "订阅者B收到新消息: " << msg << endl;
}
};
- int main()
- {
-
- News_A* New_a = new News_A;
- News_B* New_b = new News_B;
-
- Observer_A* obser_a = new Observer_A("observer_A",New_a);
- Observer_B* obser_b = new Observer_B("observer_B",New_b);
-
-
- New_a->notify("明天会下雨哦*************");
- New_b->notify("明天广场会进行发布会活动,请大家参加");
-
- return 0;
- }
-