0%

设计模式 - 创建型 - 工厂方法模式

类型 Type

  • 创建型 Creational

含义 Intent

The intent of the factory method pattern is to define an interface for creating an object, but to let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

代码 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
public abstract class DiscountService
{
public abstract int DiscountPercentage { get; }
public override string ToString() => GetType().Name;
}

public class CountryDiscountService(string countryId) : DiscountService
{
public override int DiscountPercentage
{
get
{
return countryId switch
{
"BE" => 20,
_ => 0
};
}
}
}

public class CodeDiscountService(Guid code) : DiscountService
{
public override int DiscountPercentage => 15;
}

public abstract class DiscountFactory
{
public abstract DiscountService CreateDiscountService();
}

public class CountryDiscountFactory(string countryId) : DiscountFactory
{
public override DiscountService CreateDiscountService() => new CountryDiscountService(countryId);
}

public class CodeDiscountFactory(Guid code) : DiscountFactory
{
public override DiscountService CreateDiscountService() => new CodeDiscountService(code);
}

// Client Invoke
List<DiscountFactory> factories =
[
new CountryDiscountFactory("BE"),
new CodeDiscountFactory(Guid.NewGuid())
];

foreach (var factory in factories)
{
var discountService = factory.CreateDiscountService();
Console.WriteLine(
$"Discount Service: {discountService}, Discount Percentage: {discountService.DiscountPercentage}%");
}

使用时机 Time to Use

  • When a class can not anticipate the class of objects it must create
  • When a class wants its subclasses to specify the objects it creates
  • As a way to enable reusing of existing objects

模式好坏 Pattern Consequence

  • Factory methods eliminate the need to bind application-specific classes to your code

  • New types of products can be added without breaking client code: OCP

  • Creating products is moved to one specific place in your code, the creator: SRP

  • drawback: clients might need to create subclasses of the creator class just to create a particular ConcreteProduct object