创建型之工厂模式

工厂模式

工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。实际上,如果创建对象的逻辑并不复杂,那我们直接通过 new 来创建对象就可以了,不需要使用工厂模式。当创建逻辑比较复杂,是一个“大工程”的时候,我们就考虑使用工厂模式,封装对象的创建过程,将对象的创建和使用相分离。

工厂模式包括简单工厂、工厂方法、抽象工厂这 3 种细分模式。其中,简单工厂和工厂方法比较常用,抽象工厂的应用场景比较特殊,所以很少用到。

  • 简单工厂:当每个对象的创建逻辑都比较简单的时候,我们推荐使用简单工厂模式,将多个对象的创建逻辑放到一个工厂类中。
  • 工厂方法:当每个对象的创建逻辑都比较复杂的时候,为了避免设计一个过于庞大的工厂类,我们推荐使用工厂方法模式,将创建逻辑拆分得更细,每个对象的创建逻辑独立到各自的工厂类中。
    在这里插入图片描述

简单工厂

由于 Go 本身是没有构造函数的,一般而言我们采用 NewName 的方式创建对象/接口,当它返回的是接口的时候,其实就是简单工厂模式

package main

type RuleConfig struct{}

// 解析配置文件的接口,配置文件可能有多种格式,故可能有多种解析类
// 因此定义一个接口,规范统一逻辑
type IRuleConfigParser interface {
	parse(configText string) RuleConfig
}

// 各实现类的定义
type JsonRuleConfigParser struct{}

func NewJsonRuleConfigParser() JsonRuleConfigParser {
	return JsonRuleConfigParser{}
}

// 实现了该方法,便是实现了IRuleConfigParser接口
func (parser JsonRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

type XmlRuleConfigParser struct{}

func NewXmlRuleConfigParser() XmlRuleConfigParser {
	return XmlRuleConfigParser{}
}

func (parser XmlRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

type YamlRuleConfigParser struct{}

func NewYamlRuleConfigParser() YamlRuleConfigParser {
	return YamlRuleConfigParser{}
}

func (parser YamlRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

// 简单工厂模式:对象初始化不复杂

// 工厂函数,返回的是接口,可见多个类实现了该接口,根据参数不多生产不同对象,实现了工厂模式
func CreateParser(configFormat string) IRuleConfigParser {
	if configFormat == "json" {
		return NewJsonRuleConfigParser()
	}
	if configFormat == "xml" {
		return NewXmlRuleConfigParser()
	}
	if configFormat == "yaml" {
		return NewYamlRuleConfigParser()
	}
	return nil
}

// 业务类
type RuleConfigSource struct{}

func (rcs RuleConfigSource) load(ruleConfigFilePath string) RuleConfig {
	configFormat := rcs.getFileExtension(ruleConfigFilePath)
	parser := CreateParser(configFormat)
	if parser == nil {
		panic("invalid parser")
	}

	configText := ""
	//从ruleConfigFilePath文件中读取配置文本configText到RuleConfig中
	return parser.parse(configText)
}

func (rcs RuleConfigSource) getFileExtension(filePath string) string {
	//...解析文件名获取扩展名,比如rule.json,返回json
	return "json"
}

工厂方法

package main

type RuleConfig struct{}

type IRuleConfigParser interface {
	parse(configText string) RuleConfig
}

// 各实现类的定义
type JsonRuleConfigParser struct{}

func NewJsonRuleConfigParser() JsonRuleConfigParser {
	// ...
	return JsonRuleConfigParser{}
}

func (parser JsonRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

type XmlRuleConfigParser struct{}

func NewXmlRuleConfigParser() XmlRuleConfigParser {
	// ...
	return XmlRuleConfigParser{}
}

func (parser XmlRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

type YamlRuleConfigParser struct{}

func NewYamlRuleConfigParser() YamlRuleConfigParser {
	// ...
	return YamlRuleConfigParser{}
}

func (parser YamlRuleConfigParser) parse(configText string) RuleConfig {
	return RuleConfig{}
}

// 工厂方法模式:对象初始化复杂,将创建对象的逻辑移动到工厂类
type IRuleConfigParserFactory interface {
	CreateParser() IRuleConfigParser
}

type JsonRuleConfigParserFactory struct{}

func NewJsonRuleConfigParserFactory() JsonRuleConfigParserFactory {
	// ... 
	return JsonRuleConfigParserFactory{}
}

func (factory JsonRuleConfigParserFactory) CreateParser() IRuleConfigParser {
	// do a lot of (different) things
	// 对象复杂的初始化逻辑放到了这里
	return NewJsonRuleConfigParser()
}

type XmlRuleConfigParserFactory struct{}

func NewXmlRuleConfigParserFactory() XmlRuleConfigParserFactory {
	// ...
	return XmlRuleConfigParserFactory{}
}

func (factory XmlRuleConfigParserFactory) CreateParser() IRuleConfigParser {
	// do a lot of (different) things
	return NewXmlRuleConfigParser()
}

type YamlRuleConfigParserFactory struct{}

func NewYamlRuleConfigParserFactory() YamlRuleConfigParserFactory {
	// ...
	return YamlRuleConfigParserFactory{}
}

func (factory YamlRuleConfigParserFactory) CreateParser() IRuleConfigParser {
	// do a lot of (different) things
	return NewYamlRuleConfigParser()
}

// 业务类
type RuleConfigSource struct{}

func (rcs RuleConfigSource) load(ruleConfigFilePath string) RuleConfig {
	configFormat := rcs.getFileExtension(ruleConfigFilePath)

	// if/switch 语句从简单工厂模式的 CreateParser 上移到了业务代码
	var parserFactory IRuleConfigParserFactory
	switch configFormat {
	case "json":
		parserFactory = NewJsonRuleConfigParserFactory()
	case "xml":
		parserFactory = NewXmlRuleConfigParserFactory()
	case "yaml":
		parserFactory = NewYamlRuleConfigParserFactory()
	}
	if parserFactory == nil {
		panic("invalid format")
	}
	// 由这里来创建估计的对象,CreateParser方法中封装了各个具体类复杂的初始化逻辑
	parser := parserFactory.CreateParser()

	configText := ""
	//从ruleConfigFilePath文件中读取配置文本configText到RuleConfig中
	return parser.parse(configText)
}

func (rcs RuleConfigSource) getFileExtension(filePath string) string {
	//...解析文件名获取扩展名,比如rule.json,返回json
	return "json"
}

// 工厂的工厂,上面switch的另一种实现而已
var (
	factoryMap = map[string]IRuleConfigParserFactory{
		"json": NewJsonRuleConfigParserFactory(),
		"xml":  NewXmlRuleConfigParserFactory(),
		"yaml": NewYamlRuleConfigParserFactory(),
	}
)

func GetParserFactory(format string) IRuleConfigParserFactory {
	if format == "" {
		return nil
	}
	return factoryMap[format]
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值