基于工厂模式创建对象
Factory Method
工厂模式: 在父类中提供创建对象的方法,允许子类决定实例化对象的类型
- 不使用 new 直接实例化对象,而是基于工厂方法创建对象
- 使用工厂封装对象创建过程,进行统一管理,将创建对象与使用对象的过程 解耦
- 提高代码维护性和扩展性
- 用于复杂系统生成对象,对于简单对象引入工厂类会增加系统复杂度,得不偿失
为什么使用工厂模式,以创建图形为例,不使用工厂模式,绘制图形代码如下
1 2 3 4 5 6
| Circle* circle = new Circle(); circle->draw(); Rectangle* rectangle = new Rectangle(); rectangle->draw(); Triangle* triangle = new Triangle(); triangle->draw();
|
使用工厂模式,绘制图形代码如下
1 2 3 4 5 6
| Graphic* graphic1 = GraphicFactory::createGraphic(circle); Graphic* graphic2 = GraphicFactory::createGraphic(rectangle); Graphic* graphic3 = GraphicFactory::createGraphic(triangle); graphic1->draw(); graphic2->draw(); graphic3->draw();
|
对比使用工厂模式前后差别
性质 |
常规模式 |
工厂模式 |
耦合性 |
客户端代码依赖于图形类 |
代码依赖抽象接口,修改图形实现时无需更改客户端代码 |
扩展性 |
客户端代码需要添加新图形类引用 |
修改工厂类即可添加新图形类,客户端无需修改 |
维护性 |
修改图形类需要修改所有相关客户端代码 |
修改图形类例如添加过程日志、缓存时只需修改工厂类即可 |
Implementation
- 简单工厂模式
- 结构:工厂类、抽象产品、具体产品
- 特点:工厂类封装了创建具体产品对象的函数
- 缺点:扩展性差,新增产品的时候,需要修改工厂类,违背开闭原则
- 工厂方法模式
- 结构:工厂接口、具体工厂、产品接口、具体产品
- 特点:符合开闭原则,具体工厂、具体产品可扩展,工厂类无需修改;客户端仅需关注工厂接口,无需了解具体实现
- 缺点:每新增一个具体产品就需要扩展具体工厂
- 抽象工厂模式
- 结构:抽象工厂、具体工厂、抽象产品、具体产品
- 特点:管理复杂对象依赖关系
- 缺点:系统复杂臃肿
CPP
基本结构
Member |
Full name |
Description |
工厂类 |
Factory |
基于输入创建对象 |
产品接口 |
Product Interface |
定义产品的公共接口 |
具体产品 |
Concrete Product |
定义具体产品的特定行为和属性 |
UML结构
实现步骤
- 定义产品接口
1 2 3 4 5
| class Product { public: virtual void use() = 0; virtual ~Product() {} };
|
- 定义具体产品
1 2 3 4 5 6 7 8 9
| class ConcreteProductA : public Product { public: void use() override { std::cout << "Using ConcreteProductA\n"; } };
class ConcreteProductB : public Product { public: void use() override { std::cout << "Using ConcreteProductB\n"; } };
|
- 定义工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| enum PRODUCT_TYPE { ProductA, ProductB };
class SimpleFactory { public: static Product* createProduct(PRODUCT_TYPE type) { switch (type) { case ProductA: return new ConcreteProductA(); break; case ProductB: return new ConcreteProductB(); break; default: return nullptr; break; } } };
|
- 创建产品
1 2 3 4
| Product* product = SimpleFactory::createProduct(ProductA); product->use(); delete product; product = nullptr;
|
基本结构
Member |
Full name |
Description |
工厂接口 |
Factory Interface |
定义创建具体产品接口 |
具体工厂 |
Concrete Factory |
封装创建具体产品方法 |
产品接口 |
Product Interface |
定义产品公共接口 |
具体产品 |
Concrete Product |
定义具体产品的特定行为和属性 |
UML结构
实现步骤
- 定义产品接口、工厂接口
1 2 3 4 5 6 7 8 9 10
| class Product { public: virtual void use() = 0; virtual ~Product() {} }; class Factory { public: virtual Product* createProduct() = 0; virtual ~Factory() {} };
|
- 定义具体产品、具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class ConcreteFactoryA : public Factory { public: Product* createProduct() override { return new ConcreteProductA(); } }; class ConcreteFactoryB : public Factory { public: Product* createProduct() override { return new ConcreteProductB(); } }; class ConcreteProductA : public Product { public: void use() override { std::cout << "Using ConcreteProductA\n"; } }; class ConcreteProductB : public Product { public: void use() override { std::cout << "Using ConcreteProductB\n"; } };
|
- 创建产品
1 2 3 4 5
| Factory* factory = new ConcreteFactoryA(); Product* product = factory->createProduct(); product->use(); delete product; delete factory;
|
基本结构
Member |
Full name |
Description |
抽象工厂 |
Abstract Factory |
声明创建产品的方法(接口/抽象类) |
具体工厂 |
Concrete Factory |
实现抽象工厂接口 |
抽象产品 |
Abstract Product |
定义产品的共同接口或抽象类 |
具体产品 |
Concrete Product |
定义具体产品的特定行为和属性 |
UML结构
实现步骤
- 定义抽象产品
1 2 3 4 5 6 7 8 9 10
| class AbstractProductA { public: virtual void useA() = 0; virtual ~AbstractProductA() {} }; class AbstractProductB { public: virtual void useB() = 0; virtual ~AbstractProductB() {} };
|
- 定义具体产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class ConcreteProductA1 : public AbstractProductA { public: void useA() override { std::cout << "Using ConcreteProductA1\n"; } }; class ConcreteProductB1 : public AbstractProductB { public: void useB() override { std::cout << "Using ConcreteProductB1\n"; } }; class ConcreteProductA2 : public AbstractProductA { public: void useA() override { std::cout << "Using ConcreteProductA2\n"; } }; class ConcreteProductB2 : public AbstractProductB { public: void useB() override { std::cout << "Using ConcreteProductB2\n"; } };
|
- 定义抽象工厂
1 2 3 4 5 6
| class AbstractFactory { public: virtual AbstractProductA* createProductA() = 0; virtual AbstractProductB* createProductB() = 0; virtual ~AbstractFactory() {} };
|
- 定义具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class ConcreteFactory1 : public AbstractFactory { public: AbstractProductA* createProductA() override { return new ConcreteProductA1(); } AbstractProductB* createProductB() override { return new ConcreteProductB1(); } }; class ConcreteFactory2 : public AbstractFactory { public: AbstractProductA* createProductA() override { return new ConcreteProductA2(); } AbstractProductB* createProductB() override { return new ConcreteProductB2(); } };
|
- 创建产品
1 2 3 4 5 6 7 8
| AbstractFactory* factory = new ConcreteFactory1(); AbstractProductA* productA = factory->createProductA(); AbstractProductB* productB = factory->createProductB(); productA->useA(); productB->useB(); delete productA; delete productB; delete factory;
|
Fortran
以下代码只尽量确保与 CPP 形式一致,不一定是最佳实践
实现步骤
- 定义产品接口
1 2 3 4 5 6 7 8 9 10 11 12
| module ProductInterface implicit none type, abstract :: Product contains procedure(use), nopass, deferred :: use end type Product
abstract interface subroutine use() end subroutine use end interface end module ProductInterface
|
- 定义具体产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| module ConcreteProducts use ProductInterface implicit none
type, extends(ProductClass) :: ConcreteProductA contains procedure, public, nopass :: use => use_productA end type ConcreteProductA
type, extends(ProductClass) :: ConcreteProductB contains procedure, public, nopass :: use => use_productA end type ConcreteProductB
contains subroutine use_productA() print *, "Using ConcreteProductA" end subroutine use_productA
subroutine use_productB() print *, "Using ConcreteProductB" end subroutine use_productB end module ConcreteProducts
|
- 定义工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| module SimpleFactory use ConcreteProducts implicit none
contains function createProduct(type) result(prod) integer, intent(in) :: type class(ProductClass), pointer :: prod
select case (type) case (1) allocate(ConcreteProductA :: prod) case (2) allocate(ConcreteProductB :: prod) case default error stop "Invalid product type" end select end function createProduct end module SimpleFactory
|
- 创建产品
1 2 3 4 5 6 7 8 9 10 11 12
| program TestSimpleFactory use SimpleFactory implicit none integer :: choice class(ProductClass), pointer :: product
print *, "Enter product type (1 or 2):" read(*, *) choice product => createProduct(choice) call product%use() deallocate(product) end program TestSimpleFactory
|
实现步骤
- 定义产品接口、工厂接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| module ProductInterface implicit none type, abstract :: ProductClass contains procedure(use), nopass, deferred :: use end type ProductClass
abstract interface subroutine use() end subroutine use end interface end module ProductInterface
module FactoryInterface use ProductInterface implicit none
type, abstract :: FactoryClass contains procedure(createProduct), deferred, nopass :: createProduct end type FactoryClass
abstract interface function createProduct() result(prod) import :: ProductClass class(ProductClass), pointer :: prod end function createProduct end interface end module FactoryInterface
|
- 定义具体产品、具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| module ConcreteProducts use ProductInterface implicit none
type, extends(ProductClass) :: ConcreteProductA contains procedure, nopass :: use => use_productA end type ConcreteProductA
type, extends(ProductClass) :: ConcreteProductB contains procedure, nopass :: use => use_productB end type ConcreteProductB
contains subroutine use_productA() print *, "Using ConcreteProductA" end subroutine use_productA
subroutine use_productB() print *, "Using ConcreteProductB" end subroutine use_productB end module ConcreteProducts
module ConcreteFactories use FactoryInterface use ConcreteProducts implicit none
type, extends(FactoryClass) :: ConcreteFactoryA contains procedure, nopass :: createProduct => createConcreteProductA end type ConcreteFactoryA
type, extends(FactoryClass) :: ConcreteFactoryB contains procedure, nopass :: createProduct => createConcreteProductB end type ConcreteFactoryB
contains function createConcreteProductA() result(prod) class(ProductClass), pointer :: prod allocate(ConcreteProductA :: prod) end function createConcreteProductA
function createConcreteProductB() result(prod) class(ProductClass), pointer :: prod allocate(ConcreteProductB :: prod) end function createConcreteProductB end module ConcreteFactories
|
- 创建产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| program TestFactoryMethod use ConcreteFactories use ProductInterface implicit none type(ConcreteFactoryA), pointer :: factoryA type(ConcreteFactoryB), pointer :: factoryB class(ProductClass), pointer :: productA class(ProductClass), pointer :: productB
productA => factoryA%createProduct() call productA%use() deallocate(productA)
productB => factoryB%createProduct() call productB%use() deallocate(productB) end program TestFactoryMethod
|
实现步骤
- 定义抽象产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| module AbstractProducts implicit none
type, abstract :: AbstractProductA contains procedure(useA), nopass, deferred :: useA end type AbstractProductA
type, abstract :: AbstractProductB contains procedure(useB), nopass, deferred :: useB end type AbstractProductB
abstract interface subroutine useA() end subroutine useA
subroutine useB() end subroutine useB end interface end module AbstractProducts
|
- 定义具体产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| module ConcreteProducts use AbstractProducts implicit none
type, extends(AbstractProductA) :: ProductA1 contains procedure, nopass :: useA => use_productA1 end type ProductA1
type, extends(AbstractProductB) :: ProductB1 contains procedure, nopass :: useB => use_productB1 end type ProductB1
type, extends(AbstractProductA) :: ProductA2 contains procedure, nopass :: useA => use_productA2 end type ProductA2
type, extends(AbstractProductB) :: ProductB2 contains procedure, nopass :: useB => use_productB2 end type ProductB2
contains subroutine use_productA1() print *, "Using ProductA1" end subroutine use_productA1
subroutine use_productB1() print *, "Using ProductB1" end subroutine use_productB1
subroutine use_productA2() print *, "Using ProductA2" end subroutine use_productA2
subroutine use_productB2() print *, "Using ProductB2" end subroutine use_productB2 end module ConcreteProducts
|
- 定义抽象工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| module AbstractFactorys use AbstractProducts implicit none
type, abstract :: AbstractFactory contains procedure(createProductA), deferred, nopass :: createProductA procedure(createProductB), deferred, nopass :: createProductB end type AbstractFactory
abstract interface function createProductA() result(prodA) import AbstractProductA class(AbstractProductA), allocatable :: prodA end function createProductA
function createProductB() result(prodB) import AbstractProductB class(AbstractProductB), allocatable :: prodB end function createProductB end interface end module AbstractFactorys
|
- 定义具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| module ConcreteFactories use AbstractFactorys use ConcreteProducts implicit none
type, extends(AbstractFactory) :: ConcreteFactory1 contains procedure, nopass :: createProductA => createProductA1 procedure, nopass :: createProductB => createProductB1 end type ConcreteFactory1
type, extends(AbstractFactory) :: ConcreteFactory2 contains procedure, nopass :: createProductA => createProductA2 procedure, nopass :: createProductB => createProductB2 end type ConcreteFactory2
contains function createProductA1() result(prodA) class(AbstractProductA), pointer :: prodA allocate(ProductA1 :: prodA) end function createProductA1
function createProductB1() result(prodB) class(AbstractProductB), pointer :: prodB allocate(ProductB1 :: prodB) end function createProductB1
function createProductA2() result(prodA) class(AbstractProductA), pointer :: prodA allocate(ProductA2 :: prodA) end function createProductA2
function createProductB2() result(prodB) class(AbstractProductB), pointer :: prodB allocate(ProductB2 :: prodB) end function createProductB2 end module ConcreteFactories
|
- 创建产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| program TestAbstractFactory use ConcreteFactories use AbstractProducts implicit none type(ConcreteFactory1), pointer :: factory1 type(ConcreteFactory2), pointer :: factory2 class(AbstractProductA), pointer :: productA class(AbstractProductB), pointer :: productB continue productA => factory1%createProductA() productB => factory1%createProductB() call productA%useA() call productB%useB() deallocate(productA, productB)
productA => factory2%createProductA() productB => factory2%createProductB() call productA%useA() call productB%useB() deallocate(productA, productB)
deallocate(factory1, factory2) end program TestAbstractFactory
|
Reference
Java3y | 简单工厂模式、工厂方法模式和抽象工厂模式有何区别?
菜鸟教程 | 工厂模式
小林coding | C++ 深入浅出工厂模式(初识篇)
小林coding | C++ 深入浅出工厂模式(进阶篇)