【设计模式】创建型模式02:工厂模式
·
工厂模式
OVERVIOW
工厂模式通常指的就是工厂方法模式 Factory Method,区别于简单工厂与抽象工厂模式。
- 简单工厂:创建对象交给一个工厂类,根据参数返回不同产品。缺点:增加新产品需要修改工厂类,违反开闭原则(OCP)
- 工厂模式/工厂方法:定义创建对象的抽象方法,由子类决定实例化哪个具体的类,符合开闭原则。
- 抽象工厂:强调产品族,当有多个产品等级结构时使用。
1.简单工厂
简单工厂并不是GoF设计模式圣经中的23中经典模式,而工厂模式/工厂方法,和抽象工厂才是正式的经典模式:
- 核心:创建工厂类,根据传入参数用
if-else或switch case来决定返回哪个具体产品。 - 优点:调用方不用关心对象如new,解耦了创建和使用。
- 缺点:违背开闭原则,如果要新增加产品,必须修改工厂类的内部逻辑,增加
if-else。 - 适用场景:产品种类少,且很少新增产品时。
// product.h
enum class ProductType : char {
Sheep,
Lion,
Bat,
};
class AbstractProduct {
public:
virtual void transform() = 0;
virtual void ability() = 0;
virtual ~AbstractProduct() {};
};
class SheepProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to sheep." << std::endl; }
void ability() override { std::cout << "arms are turned into goat horns." << std::endl; }
};
class LionProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to alion." << std::endl; }
void ability() override { std::cout << "breathe fire." << std::endl; }
};
class BatProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to bat." << std::endl; }
void ability() override { std::cout << "unleash the Myriad Swords." << std::endl; }
};
// factory.h
class Factory {
public:
AbstractProduct* createPorduct(ProductType type) {
AbstractProduct* product = nullptr;
switch (type) {
case ProductType::Sheep: {
product = new SheepProduct;
break;
}
case ProductType::Lion: {
product = new LionProduct;
break;
}
case ProductType::Bat: {
product = new BatProduct;
break;
}
default:
break;
}
return product;
}
};
// test.hpp
void test_simple_factory() {
auto factory = std::make_unique<Factory>();
std::unique_ptr<AbstractProduct> product(factory->createPorduct(ProductType::Lion));
if (!product) {
std::cout << "factory createPorduct failed..." << std::endl;
return;
}
product->transform();
product->ability();
}
2.工厂模式/工厂方法
- 核心:将工厂抽象化,定义创建产品的抽象方法,具体创建哪个产品由子类工厂决定(延迟实例化)。
- 优点:符合开闭原则,新增产品时只需要新增一个产品类、以及对应的工厂子类,老代码无需修改。
- 缺点:每新增一个产品,就需要增加产品类、工厂类,容易导致类爆炸。
- 适用场景:产品种类多,且经常扩展新产品。
// product.h
class AbstractProduct {
public:
virtual void transform() = 0;
virtual void ability() = 0;
virtual ~AbstractProduct() {};
};
class SheepProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to sheep." << std::endl; }
void ability() override { std::cout << "arms are turned into goat horns." << std::endl; }
};
class LionProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to alion." << std::endl; }
void ability() override { std::cout << "breathe fire." << std::endl; }
};
class BatProduct : public AbstractProduct {
public:
void transform() override { std::cout << "transform to bat." << std::endl; }
void ability() override { std::cout << "unleash the Myriad Swords." << std::endl; }
};
// factory.h
class AbstractFactory {
public:
virtual AbstractProduct* createPorduct() = 0;
virtual ~AbstractFactory() {};
};
class SheepFactory : public AbstractFactory {
public:
AbstractProduct* createPorduct() override { return new SheepProduct; }
virtual ~SheepFactory() { std::cout << "SheepFactory destructor called." << std::endl; };
};
class LionFactory : public AbstractFactory {
public:
AbstractProduct* createPorduct() override { return new LionProduct; }
virtual ~LionFactory() { std::cout << "LionFactory destructor called." << std::endl; };
};
class BatFactory : public AbstractFactory {
public:
AbstractProduct* createPorduct() override { return new BatProduct; }
virtual ~BatFactory() { std::cout << "BatFactory destructor called." << std::endl; };
};
// test.hpp
void test_factory_method() {
auto factory = std::make_unique<BatFactory>();
std::unique_ptr<AbstractProduct> product(factory->createPorduct());
if (!product) {
std::cout << "factory createPorduct failed..." << std::endl;
return;
}
product->transform();
product->ability();
}
3.抽象工厂
- 核心:不生产单一产品,而是生产整套产品(产品族)。
- 优点:保证配套产品的一致性(华为工厂生产的手机、路由器、耳机全都是同个华为工厂生产的)
- 缺点:新增产品种类较难,如果在工厂中增加
createWatch()方法,所有品牌子类工厂都得修改。 - 适用场景:系统需要更换整套外观\风格\品牌(如换一套UI主题、或切换数据库连接池\日志\缓存的全家桶)
以造船为例子:
| 基础版 | 标准版 | 旗舰版 | |
|---|---|---|---|
| 外观 | 木头 | 钢铁 | 合成金属 |
| 动力 | 手动 | 内燃机 | 核动力 |
| 武器 | 枪 | 速射炮 | 激光 |
代码实现:
// product.h
// appearance
class ShipApprearance {
public:
virtual const std::string getAppearance() = 0;
virtual ~ShipApprearance() {};
};
class ShipWoodAppearance : public ShipApprearance {
public:
const std::string getAppearance() override { return "wood appearance."; }
};
class ShipMetalAppearance : public ShipApprearance {
public:
const std::string getAppearance() override { return "metal appearance."; }
};
class ShipSyntheticAppearance : public ShipApprearance {
public:
const std::string getAppearance() override { return "synthetic appearance."; }
};
// engine
class ShipEngine {
public:
virtual const std::string getEngine() = 0;
virtual ~ShipEngine() {};
};
class ShipManualEngine : public ShipEngine {
public:
const std::string getEngine() override { return "manual engine."; }
};
class ShipSteamEngine : public ShipEngine {
public:
const std::string getEngine() override { return "steam engine."; }
};
class ShipNuclearEngine : public ShipEngine {
public:
const std::string getEngine() override { return "nuclear engine."; }
};
// weapon
class ShipWeapon {
public:
virtual const std::string getWeapon() = 0;
virtual ~ShipWeapon() {};
};
class ShipGunWeapon : public ShipWeapon {
public:
const std::string getWeapon() override { return "gun weapon."; }
};
class ShipCannonWeapon : public ShipWeapon {
public:
const std::string getWeapon() override { return "cannon weapon."; }
};
class ShipLaserWeapon : public ShipWeapon {
public:
const std::string getWeapon() override { return "laser weapon."; }
};
// ship
class Ship {
public:
Ship(ShipApprearance* appr, ShipEngine* engine, ShipWeapon* weapon)
: appearance_(appr), engine_(engine), weapon_(weapon) {};
~Ship() {};
const std::string getProperty() {
return "Ship appearance:" + appearance_->getAppearance() + " engine:" + engine_->getEngine() +
" weapon:" + weapon_->getWeapon();
}
private:
std::unique_ptr<ShipApprearance> appearance_;
std::unique_ptr<ShipEngine> engine_;
std::unique_ptr<ShipWeapon> weapon_;
};
// factory.h
class AbstractShipFactory {
public:
virtual Ship* createShip() = 0;
virtual ~AbstractShipFactory() {};
};
class BasicShipFactory : public AbstractShipFactory {
public:
Ship* createShip() override {
ShipApprearance* appr = new ShipWoodAppearance;
ShipEngine* engine = new ShipManualEngine;
ShipWeapon* weapon = new ShipGunWeapon;
return new Ship(appr, engine, weapon);
}
virtual ~BasicShipFactory() { std::cout << "BasicShipFactory destructor called." << std::endl; };
};
class StandardShipFactory : public AbstractShipFactory {
public:
Ship* createShip() override {
ShipApprearance* appr = new ShipSyntheticAppearance;
ShipEngine* engine = new ShipSteamEngine;
ShipWeapon* weapon = new ShipCannonWeapon;
return new Ship(appr, engine, weapon);
}
virtual ~StandardShipFactory() { std::cout << "StandardShipFactory destructor called." << std::endl; };
};
class AdvancedShipFactory : public AbstractShipFactory {
public:
Ship* createShip() override {
ShipApprearance* appr = new ShipMetalAppearance;
ShipEngine* engine = new ShipNuclearEngine;
ShipWeapon* weapon = new ShipLaserWeapon;
return new Ship(appr, engine, weapon);
}
virtual ~AdvancedShipFactory() { std::cout << "AdvancedShipFactory destructor called." << std::endl; };
};
// test.hpp
void test_factory_abstract() {
using namespace factory_abstract;
std::unique_ptr<AbstractShipFactory> factory;
std::unique_ptr<Ship> ship;
// basic ship
factory = std::make_unique<BasicShipFactory>();
ship.reset(factory->createShip());
if (!ship) {
std::cout << "factory createShip failed..." << std::endl;
return;
}
std::cout << ship->getProperty() << std::endl;
// standard ship
factory = std::make_unique<StandardShipFactory>();
ship.reset(factory->createShip());
if (!ship) {
std::cout << "factory createShip failed..." << std::endl;
return;
}
std::cout << ship->getProperty() << std::endl;
// advanced ship
factory = std::make_unique<AdvancedShipFactory>();
ship.reset(factory->createShip());
if (!ship) {
std::cout << "factory createShip failed..." << std::endl;
return;
}
std::cout << ship->getProperty() << std::endl;
}
更多推荐

所有评论(0)