Bootstrap

C++设计模式(工厂模式)

一、介绍

1.动机

在软件系统中,经常面临着创建对象的工作,这些对象有可能是一系列相互依赖的对象;由于需求的变化,需要创建的对象的具体类型经常变化,同时也可能会有更多系列的对象需要被创建。

如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?

 

2.定义

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。——GOF

抽象工厂模式:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。——GOF

 

3.结构图

工厂方法模式:

42ffb07cfb8048cea5e8a821a0043e38.jpeg

抽象工厂模式:

ff1b2684237c4725ac531ae5b3535925.jpeg

 

4.要点总结

工厂方法模式:

  • Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
  • Factory Method模式通过面向对象的手法,将创建具体对象的工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
  • Factory Method模式解决“单个对象”的需求变化,缺点在于要求创建方法/参数相同。

抽象工厂模式:

  • 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。
  • “系列对象”指的是在某一特定系列下的对象之间有相互依赖或相互作用的关系,不同系列的对象之间不能相互依赖。
  • Abstract Factory模式主要在于应对“新系列”的需求变动,其缺点在于难以应对“新对象”的需求变动。

 

 

二、工厂模式

1.概念

工厂模式避免直接使用new运算符来创建产品对象,它提供一个抽象的工厂接口来创建和管理对象的实例化,同时也支持对创建逻辑的封装和扩展。

①工厂模式的优点:

  • 解耦:客户端代码与具体产品的创建逻辑分离,只依赖于抽象产品和工厂接口。
  • 扩展性:增加新产品时只需添加新的具体产品类和相应的具体工厂类,不需要修改现有代码。
  • 重用性:同一个工厂类可以用来创建多个产品,提高代码的复用率。

②工厂模式的缺点:

  • 增加类的数量:可能导致系统中类的数量增加,尤其是在使用抽象工厂模式时。
  • 复杂性:引入额外的抽象层,可能会增加理解和维护的复杂性。

 

2.实现要点

  • 抽象产品:定义一个抽象产品类,它将作为具体产品的共同基类或接口。
  • 具体产品:为每个具体的产品实现一个类,这些类将继承或实现抽象产品类。
  • 抽象工厂:创建一个抽象工厂类,它将提供创建产品的接口。
  • 具体工厂:实现抽象工厂中定义的方法,创建具体的产品对象。
  • 客户端:使用工厂方法来创建对象,但不需要知道具体产品的类。

工厂模式可以分为三种类型:简单工厂模式、工厂方法模式及抽象工厂模式。

 

3.简单工厂模式

通过一个工厂类来创建不同类型的产品实例,根据传递的参数来决定创建哪种具体的产品。

//文具类(抽象产品)
class Stationery {
public:
	virtual void use() = 0;
	virtual ~Stationery() {}
};

//钢笔类(具体产品)
class Pen :public Stationery {
public:
	Pen() {
		cout << "Pen()" << endl;
	}
	virtual ~Pen() {
		cout << "~Pen()" << endl;
	}
	virtual void use() override{
		cout << "Use pen." << endl;
	}
};

//铅笔类(具体产品)
class Pencil :public Stationery {
public:
	Pencil() {
		cout << "Pencil()" << endl;
	}
	virtual ~Pencil() {
		cout << "~Pencil()" << endl;
	}
	virtual void use() override {
		cout << "Use pencil." << endl;
	}
};

//枚举类型
enum StationeryType {
	PEN,
	PENCIL
};

//文具工厂类
class StationeryFactory {
public:
	static shared_ptr<Stationery> createStationery(StationeryType type) {
		switch (type) {
		case PENCIL:
			return shared_ptr<Stationery>(new Pencil);
			break;
		case PEN:
			return shared_ptr<Stationery>(new Pen);
			break;
		defalut:
			return nullptr;
			break;
		}
	}
};

 测试代码:

shared_ptr<Stationery> pen = StationeryFactory::createStationery(PEN);
pen->use();
shared_ptr<Stationery> pencil = StationeryFactory::createStationery(PENCIL);
pencil->use();

 输出结果;

Pen()
Use pen.
Pencil()
Use pencil.
~Pencil()
~Pen()

 

4.工厂方法模式

将创建具体产品的任务分发给具体的产品工厂,每个具体工厂负责创建对应的具体产品对象。

//交通工具类(抽象类)
class Vehicle {
public:
	virtual void run() = 0;
	virtual ~Vehicle() {}
};

//汽车类(具体类)
class Car :public Vehicle {
public:
	virtual void run() override {
		cout << "The car is running." << endl;
	}
};

//自行车类(具体类)
class Bicycle :public Vehicle {
public:
	virtual void run() override {
		cout << "The bicycle is moving." << endl;
	}
};

//交通工具工厂(抽象工厂)
class VehicleFactory {
public:
	virtual Vehicle* createVehicle() = 0;
	virtual ~VehicleFactory() {}
};

//汽车工厂(具体工厂)
class CarFactory :public VehicleFactory {
public:
	virtual Vehicle* createVehicle() override {
		return new Car();
	}
};

//自行车工厂(具体工厂)
class BicycleFactory :public VehicleFactory {
public:
	virtual Vehicle* createVehicle() override {
		return new Bicycle();
	}
};

测试代码: 

VehicleFactory* carFactory = new CarFactory();
Vehicle* car = carFactory->createVehicle();
car->run();
delete car;
delete carFactory;

VehicleFactory* bicycleFactory = new BicycleFactory();
Vehicle* bicycle = bicycleFactory->createVehicle();
bicycle->run();
delete bicycle;
delete bicycleFactory;

输出结果: 

The car is running.
The bicycle is moving.

 

5.抽象工厂模式

提供一个抽象的工厂接口以及多个具体工厂类,每个具体工厂类负责创建一种或多种产品。

//桌子类(抽象类)
class Table {
public:
	virtual void display() = 0;
	virtual ~Table() {}
};

//现代风格桌子(具体类)
class ModernTable :public Table {
public:
	virtual void display() override {
		cout << "A modern style table." << endl;
	}
};

//古典风格桌子(具体类)
class ClassicalTable :public Table {
public:
	virtual void display() override {
		cout << "A classical style table." << endl;
	}
};

//椅子类(抽象类)
class Chair {
public:
	virtual void sit() = 0;
	virtual ~Chair() {}
};

//现代风格椅子(具体类)
class ModernChair :public Chair {
public:
	virtual void sit() override {
		cout << "Sitting on modern style chair." << endl;
	}
};

//古典风格椅子(具体类)
class ClassicalChair :public Chair {
public:
	virtual void sit() override {
		cout << "Sitting on classical style chair." << endl;
	}
};

//沙发类(抽象类)
class Sofa {
public:
	virtual void relax() = 0;
	virtual ~Sofa() {}
};

//现代风格沙发(具体类)
class ModernSofa :public Sofa {
public:
	virtual void relax() override {
		cout << "Relaxing on modern style sofa." << endl;
	}
};

//古典风格沙发(具体类)
class ClassicalSofa :public Sofa {
public:
	virtual void relax() override {
		cout << "Relaxing on Classical style sofa." << endl;
	}
};

//家具工厂(抽象工厂)
class FurnitureFactory {
public:
	virtual Table* createTable() = 0;
	virtual Chair* createChair() = 0;
	virtual Sofa* createSofa() = 0;
	virtual ~FurnitureFactory() {}
};

//现代风格家具工厂(具体工厂)
class ModernFurnitureFactory :public FurnitureFactory {
public:
	virtual Table* createTable() override {
		return new ModernTable;
	}
	virtual Chair* createChair() override {
		return new ModernChair;
	}
	virtual Sofa* createSofa() override {
		return new ModernSofa;
	}
};

//古典风格家具工厂(具体工厂)
class ClassicalFurnitureFactory :public FurnitureFactory {
public:
	virtual Table* createTable() override {
		return new ClassicalTable;
	}
	virtual Chair* createChair() override {
		return new ClassicalChair;
	}
	virtual Sofa* createSofa() override {
		return new ClassicalSofa;
	}
};

测试代码: 

FurnitureFactory* modernFactory = new ModernFurnitureFactory();
Table* modernTable = modernFactory->createTable();
Chair* modernChair = modernFactory->createChair();
Sofa* modernSofa = modernFactory->createSofa();
modernTable->display();
modernChair->sit();
modernSofa->relax();
delete modernTable;
delete modernChair;
delete modernSofa;

FurnitureFactory* classicalFactory = new ClassicalFurnitureFactory();
Table* classicalTable = new ClassicalTable();
Chair* classicalChair = new ClassicalChair();
Sofa* classicalSofa = new ClassicalSofa();
classicalTable->display();
classicalChair->sit();
classicalSofa->relax();
delete classicalTable;
delete classicalChair;
delete classicalSofa;

 输出结果:

A modern style table.
Sitting on modern style chair.
Relaxing on modern style sofa.
A classical style table.
Sitting on classical style chair.
Relaxing on Classical style sofa.

 

 

 

;