一、介绍
1.动机
在软件系统中,经常面临着创建对象的工作,这些对象有可能是一系列相互依赖的对象;由于需求的变化,需要创建的对象的具体类型经常变化,同时也可能会有更多系列的对象需要被创建。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
2.定义
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。——GOF
抽象工厂模式:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。——GOF
3.结构图
工厂方法模式:
抽象工厂模式:
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.