一、理论知识

工厂模式的作用就是用来创建对象,细分为三种:简单工厂、工厂方法、抽象工厂。

1.1 应用场景

工厂模式一般用于对于不同的场景,需要创建不同的对象,但是这些对象实现的功能是很相似的,可以抽象出一个父类,对于这种情形就可以使用工厂模式。

在实际中,很多框架都支持多种配置文件,项目启动时解析配置文件,将文件内容写入到内存中。配置文件格式很多,有xml、json、yaml等,这个时候就需要根据后缀来解析文件,使用工厂模式就很合理。

1.2 如何抉择简单工厂与工厂方法

之所以将某个代码块剥离出来,独立为函数或者类,原因是这个代码块的逻辑过于复杂,剥离之后能让代码更加清晰,更加可读、可维护。但是,如果代码块本身并不复杂,就几行代码而已,我们完全没必要将它拆分成单独的函数或者类。

基于这个设计思想,当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。而使用简单工厂模式,将所有的创建逻辑都放到一个工厂类中,会导致这个工厂类变得很复杂。

工厂方法模式比起简单工厂模式更加符合开闭原则。

二、代码实现

2.1 简单工厂实现

package b_factory

// ConfigParse 配置解析接口
type ConfigParse interface {
	Parse(path string) string
}

// JsonConfigParse Json解析类
type JsonConfigParse struct {
}

func (json *JsonConfigParse) Parse(path string) string {
	return "Json" + path
}

// XmlConfigParse xml解析类
type XmlConfigParse struct {
}

func (xml *XmlConfigParse) Parse(path string) string {
	return "XML" + path
}

// SimpleParseFactory 简单工厂
type SimpleParseFactory struct {
}

func (simple *SimpleParseFactory) create(ext string) ConfigParse {
	switch ext {
	case "json":
		// 这里是简单构造逻辑
		return &JsonConfigParse{}
	case "xml":
		// 这里是简单构造逻辑
		return &XmlConfigParse{}
	}
	return nil
}

2.2 工厂方法实现

package b_factory

// NormalParseFactory 工厂方法
type NormalParseFactory interface {
	createParse() ConfigParse
}

type JsonNormalParseFactory struct {
}

func (json *JsonNormalParseFactory) createParse() ConfigParse {
	// 假装此处有复杂的构造逻辑
	return &JsonConfigParse{}
}

type XmlNormalParseFactory struct {
}

func (xml *XmlNormalParseFactory) createParse() ConfigParse {
	// 假装此处有复杂的构造逻辑
	return &XmlConfigParse{}
}

// createFactory 创建工厂
func createFactory(ext string) NormalParseFactory {
	switch ext {
	case "json":
		return &JsonNormalParseFactory{}
	case "xml":
		return &XmlNormalParseFactory{}
	}
	return nil
}