设计模式<创建型> | 工厂模式

简单工厂(Factory Pattern)

简单工厂(静态工厂)可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个工厂类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

结构图:

角色:

  1. 简单工厂(FactoryProduct):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  2. 抽象产品(IProduct):创建的所有产品的父类,负责描述所有实例共有的公共接口。
  3. 具体产品(Product):具体的细化的产品

适用场景:

  1. 创建较少的产品/对象,且客户端不关心创建过程。

优点:

  1. 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。很方便的创建出相应的产品。工厂和产品的职责区分明确。
  2. 屏蔽了产品的具体创建过程。使用中只需要知道自己需要哪种产品即可。

缺点:

  1. 随着产品的增多 Factory 里面的代码会越来越臃肿,稍微不符合开闭原则。
  2. Factory 职责过于重,一旦这个工厂不能正常工作,整个系统都会受到影响。
  3. 工厂适用了静态方法,不能被继承和重写。

代码(C#)

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
51
52
53
54
55

/// <summary>
/// 抽象产品
/// </summary>
public interface IProduct
{
void ShowProduct();
}

/// <summary>
/// 具体产品
/// </summary>
public class Product1 : IProduct
{
public void ShowProduct()
{
Console.WriteLine("Product1");
}
}

/// <summary>
/// 具体产品
/// </summary>
public class Product2 : IProduct
{
public void ShowProduct()
{
Console.WriteLine("Product2");
}
}

/// <summary>
/// 简单工厂
/// </summary>
public class FactoryProduct
{
public static IProduct CreateProduct(int productId)
{
switch (productId)
{
case 1:
return new Product1();
case 2:
return new Product1();
default:
return null;
}
}
}

var product1 = FactoryProduct.CreateProduct(1);
product1.ShowProduct();
var product2 = FactoryProduct.CreateProduct(2);
product2.ShowProduct();

工厂方法(Factory Method)

如果要去掉简单工厂中繁琐的判断,传统的方法就是利用多态为每个产品创建自己的工厂,因为添加新的产品不需要修改原有代码。所以工厂方法模式比起简单工厂模式更加符合开闭原则。

结构图

角色:

  1. 抽象工厂(IFactory):抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
  2. 抽象产品(IProduct):创建的所有产品的父类,负责描述所有实例共有的公共接口。
  3. 具体产品(Product):是抽象产品的多种不同类型实现
  4. 具体产品工厂(ProductFactory):具体产品的工厂。抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法。

适用场景:

  1. 无法预知对象类别及其依赖关系时,可使用工厂方法,用子类来决定类别。

优点:

  1. 增加产品部不需要修改原有代码符合开闭原则。
  2. 一个工厂只负责一个产品的创建符合职责单一原则。

缺点:

  1. 工厂模式需要额外创建诸多 Factory 类,增加代码的复杂性。

代码(C#)

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

/// <summary>
/// 抽象产品
/// </summary>
public interface IProduct
{
void ShowProduct();
}

/// <summary>
/// 抽象工厂
/// </summary>
public interface IFactory
{
IProduct CreateProduct();
}

/// <summary>
/// 具体产品
/// </summary>
public class Product1 : IProduct
{
public void ShowProduct()
{
Console.WriteLine("Product1");
}
}

/// <summary>
/// 具体工厂
/// </summary>
public class Product1Factory : IFactory
{
public IProduct CreateProduct()
{
return new Product1();
}
}

/// <summary>
/// 具体产品
/// </summary>
public class Product2 : IProduct
{
public void ShowProduct()
{
Console.WriteLine("Product1");
}
}

/// <summary>
/// 具体工厂
/// </summary>
public class Product2Factory : IFactory
{
public IProduct CreateProduct()
{
return new Product1();
}
}

// 创建具体产品工厂
IFactory product1Factory = new Product1Factory();
var pro1 = product1Factory.CreateProduct();
pro1.ShowProduct();


IFactory product2Factory = new Product2Factory();
var pro2 = product2Factory.CreateProduct();
pro1.ShowProduct();

抽象工厂(Abstract Factory)

抽象工厂对工厂的抽象化,让一个工厂生产一类产品。解决了按照工厂方法和简单工厂造成的工厂泛滥。

抽象工厂将各种产品分门别类,基于此来规划各种工厂的制造接口。譬如实例代码中,小米和苹果工厂不仅能生产手机还可以生产电脑或其他的产品。

结构图:

角色:

  1. 抽象产品(Abstract Product):创建的所有产品的父类,负责描述所有实例共有的公共接口。
  2. 具体产品(Concrete Product):是抽象产品的多种不同类型实现。
  3. 抽象工厂(Abstract Factory):一组创建各种抽象产品的方法
  4. 具体工厂(Concrete Factory):产出具体的产品。

适用场景:

  1. 有一个基于一组抽象方法/接口的对象,且其主要功能因此变得不明确,那么在这种情况下可以考虑使用抽象工厂模式。

优点:

  1. 同一工厂生成的产品相互匹配。
  2. 抽象后的工厂更加符合单一原则。
  3. 新增产品变体不时不需要修改原有代码符合开闭原则。
  4. 避免客户端和具体产品代码的耦合。

缺点:

  1. 代码复杂度高。

代码(C#)

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/// <summary>
/// 抽象手机产品
/// </summary>
interface IPhone
{
void ShowPhone();
}

/// <summary>
/// 抽象电脑产品
/// </summary>
interface IComputer
{
void ShowComputer();
}

/// <summary>
/// 苹果具象产品
/// </summary>
class ApplePhone : IPhone
{
public void ShowPhone()
{
Console.WriteLine("iphone 12");
}
}

class AppleComputer : IComputer
{
public void ShowComputer()
{
Console.WriteLine("mac book pro M1");
}
}

/// <summary>
/// 小米具象产品
/// </summary>
class MiPhone : IPhone
{
public void ShowPhone()
{
Console.WriteLine("mi 13");
}
}

class MiComputer : IComputer
{
public void ShowComputer()
{
Console.WriteLine("mi book");
}
}

/// <summary>
/// 抽象工厂
/// </summary>
interface IAbstractFactory
{
IPhone CreatePhone();
IComputer CreateComputer();
}

/// <summary>
/// 苹果工厂
/// </summary>
class AppleFactory : IAbstractFactory
{
public IPhone CreatePhone()
{
return new ApplePhone();
}

public IComputer CreateComputer()
{
return new AppleComputer();
}
}

/// <summary>
/// 小米工厂
/// </summary>
class MiFactory : IAbstractFactory
{
public IPhone CreatePhone()
{
return new MiPhone();
}

public IComputer CreateComputer()
{
return new MiComputer();
}
}

IAbstractFactory appleFactory = new AppleFactory();
appleFactory.CreateComputer();
appleFactory.CreatePhone();

IAbstractFactory miFactory = new MiFactory();
miFactory.CreateComputer();
miFactory.CreatePhone();\

最后

工厂模式和抽象工厂应该是项目中常用的设计模式,抽象工厂通常基于一组工厂方法来实现的。.Net中的Dependency Injection底层也是基于工厂模式来实现的,DI就相当于一个工厂,负责在程序启动的时候,根据配置事先创建好对象。当应用程序需要使用某个类对象的时候,直接从容器中获取即可。


设计模式<创建型> | 工厂模式
http://example.com/posts/35238.html
作者
她微笑的脸y
发布于
2023年2月21日
许可协议