创建型-工厂模式

工厂模式

工厂模式(Factory Design Pattern)

定义

通过工厂类来实现对象实例的创建,以达到对象的创建和使用解耦的目的

应用场景

  1. 封装变化

    对象的创建逻辑可能有变化,封装成工厂类后,创建逻辑的变化对调用者透明

  2. 代码复用

    创建逻辑剥离到独立的工厂类后可以复用

  3. 隔离复杂性

    封装复杂的创建逻辑,调用者无需了解如何创建对象

  4. 控制复杂度

    将对象的创建逻辑剥离出来,让原本的函数或类的职责更单一,代码更简洁

常见形式

1. 简单工厂模式(Simple Factory Pattern)

在简单工厂模式中,可以根据参数的不同返回不同类的实例。也可以将简单工厂模式看做是工厂模式的特例。

2. 工厂模式(Factory Pattern)

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这个子类工厂往往是同一个主题下的子类。

3.抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。一般来说我们可以让一个工厂负责创建多个不同类型的对象

Go源码实现

简单工厂模式

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
package factory

type IConfigParser interface {
Parser()
}

type JsonConfigParser struct {
}

func (j JsonConfigParser) Parser() {
}

type XmlConfigParser struct {
}

func (x XmlConfigParser) Parser() {
}

func NewConfigParser(t string) IConfigParser {
switch t {
case "json":
return JsonConfigParser{}
case "xml":
return XmlConfigParser{}
}
return nil
}

通过NewConfigParser()方法来创建不同的文件解析器,可以认为NewConfigParser就是一个简单工厂的入口。

带缓存的简单工厂

若每次创建的解析器都一致,可以将解析器缓存到map中,每次根据输入来取出对应已的解析器,避免重复创建。

1
2
3
4
5
6
7
8
9
10
var parserCache map[string]IConfigParser

func init() {
parserCache["json"] = JsonConfigParser{}
parserCache["xml"] = XmlConfigParser{}
}

func NewCachedConfigParser(t string) IConfigParser {
return parserCache[t]
}

工厂模式

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
package factory

type IConfigParserFactory interface {
CreateParser() IConfigParser
}

type JosnConfigParserFactory struct {
}

func (j JosnConfigParserFactory) CreateParser() IConfigParser {
return JsonConfigParser{}
}

type XmlConfigParserFactory struct {
}

func (x XmlConfigParserFactory) CreateParser() IConfigParser {
return XmlConfigParser{}
}

func NewConfigFactory(t string) IConfigParserFactory {
switch t {
case "json":
return JosnConfigParserFactory{}
case "xml":
return XmlConfigParserFactory{}
}
return nil
}

通过NewConfigFactory()函数创建不同的工厂,再有工厂来创建对应的解析器,其实这里的也可以增加缓存具体的工厂来实现代码的进一步优化。

当什么时候适合用工厂模式而不是简单工厂?若对象的创建比较复杂时,通过不同的工厂来封装不同对象的创建过程。

抽象工厂模式

如果我们创建的解析器,既可以按照配置文件格式来分类,也可以按照解析的对象(Rule配置文件还是System系统配置)来分类,那我们会有如下4种parser类

1
2
3
4
5
JsonRuleConfigParser()
XmlRuleConfigParser()

JsonSystemConfigParser()
XmlRuleConfigParser()

我们可以让一个工厂来创建多个不同类型的对象(IRuleConfigParser、ISystemConfigParser等),这样可以有效的减少工厂类的个数

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
// 抽象工厂
type IAbstractConfigParserFactory interface {
CreateRuleConfigParser() IRuleConfigParser
CreateSystemConfigParser() ISystemConfigParser
}

// 具体工厂
type JsonConfigParserFactory struct {
}

type XmlConfigParserFactory struct {
}

func (j JsonConfigParserFactory) CreateRuleConfigParser() IRuleConfigParser {
return JsonRuleConfigParser{}
}

func (j JsonConfigParserFactory) CreateSystemConfigParser() ISystemConfigParser {
return JsonSystemConfigParser{}
}

func (x XmlConfigParserFactory) CreateRuleConfigParser() IRuleConfigParser {
return XmlRuleConfigParser{}
}

func (x XmlConfigParserFactory) CreateSystemConfigParser() ISystemConfigParser {
return XmlSystemConfigParser{}
}