0%

设计模式 - 创建型 - 抽象工厂模式

类型 Type

  • 创建型 Creational

含义 Intent

The intent of the abstract factory pattern is to provide an interface for creating families of related or dependent objects without specifying their concrete classes

代码 Code

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
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractFactory
{
public class FranceShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
{
public IDiscountService CreateDiscountService()
{
return new FranceDiscountService();
}

public IShippingCostsService CreateShippingCostsService()
{
return new FranceShippingCostsService();
}
}

/// <summary>
/// AbstractFactory
/// </summary>
public interface IShoppingCartPurchaseFactory
{
IDiscountService CreateDiscountService();
IShippingCostsService CreateShippingCostsService();
}

/// <summary>
/// AbstractProduct
/// </summary>
public interface IDiscountService
{
int DiscountPercentage { get; }
}

/// <summary>
/// ConcreteProduct
/// </summary>
public class BelgiumDiscountService : IDiscountService
{
public int DiscountPercentage => 20;
}

/// <summary>
/// ConcreteProduct
/// </summary>
public class FranceDiscountService : IDiscountService
{
public int DiscountPercentage => 10;
}

/// <summary>
/// AbstractProduct
/// </summary>
public interface IShippingCostsService
{
decimal ShippingCosts { get; }
}

/// <summary>
/// ConcreteProduct
/// </summary>
public class BelgiumShippingCostsService : IShippingCostsService
{
public decimal ShippingCosts => 20;
}

/// <summary>
/// ConcreteProduct
/// </summary>
public class FranceShippingCostsService : IShippingCostsService
{
public decimal ShippingCosts => 25;
}


public class BelgiumShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
{
public IDiscountService CreateDiscountService()
{
return new BelgiumDiscountService();
}

public IShippingCostsService CreateShippingCostsService()
{
return new BelgiumShippingCostsService();
}
}

/// <summary>
/// Client class
/// </summary>
public class ShoppingCart
{
private readonly IDiscountService _discountService;
private readonly IShippingCostsService _shippingCostsService;
private int _orderCosts;

// Constructor
public ShoppingCart(IShoppingCartPurchaseFactory factory)
{
_discountService = factory.CreateDiscountService();
_shippingCostsService = factory.CreateShippingCostsService();
// assume that the total cost of all the items we ordered = 200 euro
_orderCosts = 200;
}

public void CalculateCosts()
{
Console.WriteLine($"Total costs = {_orderCosts - (_orderCosts / 100 * _discountService.DiscountPercentage) + _shippingCostsService.ShippingCosts }");
}
}
}

抽象工厂 VS 工厂方法 Comparison

目的不同

  • 工厂方法:创建单一产品的实例

  • 抽象工厂:创建产品族 (多个相关产品)

结构复杂度

  • 工厂方法:1个抽象产品 + N 个具体工厂

  • 抽象工厂:M 个抽象产品 + N 个具体工厂 (每个工厂生产 M 个产品)

扩展方向

  • 工厂方法:扩展新产品类型时需要修改工厂接口

  • 抽象工厂:扩展新产品族时不用修改接口

简单记忆:

  • 工厂方法:1个工厂 -> 一种产品

  • 抽象工厂:1个工厂 -> 一套产品