设计模式-工厂模式

基于工厂模式创建对象

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

  1. 简单工厂模式
    • 结构:工厂类、抽象产品、具体产品
    • 特点:工厂类封装了创建具体产品对象的函数
    • 缺点:扩展性差,新增产品的时候,需要修改工厂类,违背开闭原则
  2. 工厂方法模式
    • 结构:工厂接口、具体工厂、产品接口、具体产品
    • 特点:符合开闭原则,具体工厂、具体产品可扩展,工厂类无需修改;客户端仅需关注工厂接口,无需了解具体实现
    • 缺点:每新增一个具体产品就需要扩展具体工厂
  3. 抽象工厂模式
    • 结构:抽象工厂、具体工厂、抽象产品、具体产品
    • 特点:管理复杂对象依赖关系
    • 缺点:系统复杂臃肿

CPP

基本结构

Member Full name Description
工厂类 Factory 基于输入创建对象
产品接口 Product Interface 定义产品的公共接口
具体产品 Concrete Product 定义具体产品的特定行为和属性

UML结构

实现步骤

  1. 定义产品接口
1
2
3
4
5
class Product {
public:
virtual void use() = 0;
virtual ~Product() {}
};
  1. 定义具体产品
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. 定义工厂类
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. 创建产品
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. 定义产品接口、工厂接口
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. 定义具体产品、具体工厂
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. 创建产品
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. 定义抽象产品
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. 定义具体产品
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. 定义抽象工厂
1
2
3
4
5
6
class AbstractFactory {
public:
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
virtual ~AbstractFactory() {}
};
  1. 定义具体工厂
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. 创建产品
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. 定义产品接口
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. 定义具体产品
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. 定义工厂类
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. 创建产品
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. 定义产品接口、工厂接口
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. 定义具体产品、具体工厂
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. 创建产品
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. 定义抽象产品
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. 定义具体产品
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. 定义抽象工厂
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. 定义具体工厂
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. 创建产品
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++ 深入浅出工厂模式(进阶篇)

0%