之前整个设计模式的专栏是看了李建忠老师的视频,并没有太多的自己的总结,今天来回看一下设计模式,重温设计模式的魅力
工厂模式我们介绍三个:
简单工厂
工厂方法
抽象工厂
我们举个例子,现在世界上有三场备受关注的战争。俄罗斯保护卢甘斯克和顿涅斯克独立共和国之战,加沙保卫战和果敢电诈反击战。
有战争就需要武器,这个时候他们需要枪,炮,无人机等等。他们就有了对武器的需求。
例子如下:
#include
#include
using namespace std;
class Weapon
{
public:
explicit Weapon(const string &name) {
name_ = name;
if (name == "枪") {}
else if (name == "炮") {}
else if (name == "飞机") {}
}
void useWeapon() {
if (name_ == "枪") {
cout << "我是枪" << endl;
} else if (name_ == "炮") {
cout << "我是炮" << endl;
} else if (name_ == "飞机") {
cout << "我是飞机" << endl;
}
}
private:
string name_;
};
int main()
{
Weapon gun = Weapon("枪");
Weapon cannon = Weapon("炮");
Weapon plane = Weapon("飞机");
gun.useWeapon();
cannon.useWeapon();
plane.useWeapon();
return 0;
}
从上面的例子中我们能看到,如果我们需要大量型号武器的话,Weapon明显会是一个巨大的类。该类设计时候存在以下的问题:
我们需要一种方式,来创建不同的武器,并且使得我们使用的时候,分的清楚,拿过来就用。以便我们更快获取战争的胜利。
如上述的例子:我们需要一个武器工厂,使用武器工厂来生产不同的武器,则修改为如下方式:
#include
#include
using namespace std;
class Weapon
{
public:
virtual ~Weapon() {}
virtual void useWeapon() = 0;
};
class Gun : public Weapon
{
public:
void useWeapon() override
{
cout << "我是枪" << endl;
}
};
class Cannon : public Weapon
{
public:
void useWeapon() override
{
cout << "我是炮" << endl;
}
};
class Plane : public Weapon
{
public:
void useWeapon() override
{
cout << "我是飞机" << endl;
}
};
class Factory
{
public:
Weapon *createWeapon(const std::string &name)
{
if (name == "枪") {
return new Gun;
} else if (name == "炮") {
return new Cannon;
} else if (name == "飞机") {
return new Plane;
}
}
};
int main()
{
Factory ff;
Weapon* weapon = nullptr;
weapon = ff.createWeapon("枪");
weapon->useWeapon();
delete weapon;
weapon = nullptr;
weapon = ff.createWeapon("炮");
weapon->useWeapon();
delete weapon;
weapon = nullptr;
weapon = ff.createWeapon("飞机");
weapon->useWeapon();
delete weapon;
weapon = nullptr;
return 0;
}
如上例子所示,我们需要生产武器种类多的时候,工厂就会变的臃肿。但是我们使用的时候,只要抽象一个武器,工厂负责生产,且生产的武器我们直接拿来使用就可以。因为工厂生产的是具体的武器,所以我们在使用的时候会用具体的武器去击败敌人。
简单工厂的优缺点也很明显了:
简单工厂适合工厂产品较少,客户端只需要告诉工厂需要生产对应的产品,对如何创建不关心的场景
角色和对应的职责:
我们使用简单工厂生产武器的时候,工厂堆积严重,因此我们需要一个工厂调度中心,然后将武器分给不同的工厂分别生产,代码如下:
#include
#include
using namespace std;
class Weapon
{
public:
virtual ~Weapon() {}
virtual void useWeapon() = 0;
};
class Gun : public Weapon
{
public:
void useWeapon() override
{
cout << "我是枪" << endl;
}
};
class Cannon : public Weapon
{
public:
void useWeapon() override
{
cout << "我是炮" << endl;
}
};
class Plane : public Weapon
{
public:
void useWeapon() override
{
cout << "我是飞机" << endl;
}
};
class AbstractFactory
{
public:
virtual Weapon *createWeapon() = 0;
};
class GunFactory : public AbstractFactory
{
public:
Weapon *createWeapon() override
{
return new Gun;
}
};
class CannonFactory : public AbstractFactory
{
public:
Weapon *createWeapon() override
{
return new Cannon;
}
};
class PlaneFactory : public AbstractFactory
{
public:
Weapon *createWeapon() override
{
return new Plane;
}
};
int main()
{
AbstractFactory *ff = nullptr;
Weapon* weapon = nullptr;
ff = new GunFactory;
weapon = ff->createWeapon();
weapon->useWeapon();
delete weapon;
weapon = nullptr;
delete ff;
ff = nullptr;
ff = new CannonFactory;
weapon = ff->createWeapon();
weapon->useWeapon();
delete weapon;
weapon = nullptr;
delete ff;
ff = nullptr;
ff = new PlaneFactory;
weapon = ff->createWeapon();
weapon->useWeapon();
delete weapon;
weapon = nullptr;
delete ff;
ff = nullptr;
return 0;
}
优缺点:
优点:不需要记住具体的武器名字,甚至不需要对应的参数;实现了创建和使用的分离;系统扩展性变好,如果有新的武器,不需要修改原来的接口和类。
缺点:增加了类的数量,增加了抽象性和理解难度
工厂分类明确,职责清晰。如果我们某类型的武器不足,只需要到对应类型的工厂去取即可。
工厂方法通过引入工厂调度中心,解决了简单工厂中工厂类职责过重的问题,但是由于工厂方法中的每个工厂只生产一类产品,导致我们工厂非常多,肯定会增加系统的开销,因此我们考虑将一些产品组成一类,使用同一个工厂生产。
比如我们在俄罗斯生产一种型号的枪炮飞机,在朝鲜生产另外一种型号的枪炮飞机,则武器供应不断,胜利就在眼前。
角色和对应的职责:
#include
#include
using namespace std;
class WeaponGun
{
public:
virtual void useWeapon() = 0;
};
class WeaponPlane
{
public:
virtual void useWeapon() = 0;
};
class WeaponCannon
{
public:
virtual void useWeapon() = 0;
};
class TMXGun : public WeaponGun
{
public:
void useWeapon() override
{
cout << "使用汤姆逊" << endl;
}
};
class JKSGun : public WeaponGun
{
public:
void useWeapon() override
{
cout << "使用捷克式" << endl;
}
};
class WeaponCannon1 : public WeaponCannon
{
public:
void useWeapon() override
{
cout << "二营长的意大利炮" << endl;
}
};
class WeaponCannon2 : public WeaponCannon
{
public:
void useWeapon() override
{
cout << "二营长的迫击炮" << endl;
}
};
class WeaponPlane1 : public WeaponPlane
{
public:
void useWeapon() override
{
cout << "战斗机" << endl;
}
};
class WeaponPlane2 : public WeaponPlane
{
public:
void useWeapon() override
{
cout << "轰炸机" << endl;
}
};
class AbstractFactory {
public:
virtual WeaponGun* createGun() = 0;
virtual WeaponCannon* createCannon() = 0;
virtual WeaponPlane* createPlane() = 0;
};
class RussiaFactory : public AbstractFactory
{
public:
WeaponGun* createGun() override {
return new TMXGun;
}
WeaponCannon* createCannon() override
{
return new WeaponCannon1;
}
WeaponPlane* createPlane() override
{
return new WeaponPlane1;
}
};
class NorthKoreaFactory : public AbstractFactory
{
public:
WeaponGun* createGun() override {
return new JKSGun;
}
WeaponCannon* createCannon() override
{
return new WeaponCannon2;
}
WeaponPlane* createPlane() override
{
return new WeaponPlane2;
}
};
int main()
{
AbstractFactory *factory = nullptr;
WeaponGun *gun = nullptr;
WeaponCannon *cannon = nullptr;
WeaponPlane *plane = nullptr;
factory = new RussiaFactory;
gun = factory->createGun();
cannon = factory->createCannon();
plane = factory->createPlane();
gun->useWeapon();
cannon->useWeapon();
plane->useWeapon();
delete factory;
delete gun;
delete cannon;
delete plane;
factory = new NorthKoreaFactory;
gun = factory->createGun();
cannon = factory->createCannon();
plane = factory->createPlane();
gun->useWeapon();
cannon->useWeapon();
plane->useWeapon();
delete factory;
delete gun;
delete cannon;
delete plane;
return 0;
}
至此,多地共同生产产品,战争胜利近在眼前。