工厂模式
工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
实际上,如果创建对象的逻辑并不复杂,那我们直接通过 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]
}