简单工厂模式适用于创建单一类型的不同对象,通过一个工厂函数根据参数返回具体实现,适合产品种类少且变化不频繁的场景;抽象工厂模式则用于创建一组相关或依赖的对象家族,通过定义抽象工厂接口和多个具体工厂来保证产品间的一致性,适合需要整体切换产品族的复杂系统。两者核心区别在于简单工厂关注单个对象创建,抽象工厂关注多个关联对象的批量创建与组合,选择时需权衡系统复杂度、扩展需求及维护成本,go语言中利用接口特性可简洁实现这两种模式,但应避免过度设计,优先选用最匹配当前场景的方案。

工厂模式在Go语言中,本质上是一种创建型设计模式,它将对象的创建过程封装起来,让调用者无需关心具体创建哪个类,只需通过一个统一的接口或函数来获取所需对象。简单工厂模式通常用于创建一系列同类型但不同配置的对象,而抽象工厂模式则更进一步,它负责创建一系列相关或相互依赖对象的家族,而无需指定它们具体的类。在我看来,这两种模式在Go里用起来都挺顺手,但它们解决的问题和适用的场景却大相径庭。
在Go语言中实现工厂模式,我们通常会利用其强大的接口(interface)特性。
简单工厂模式(Simple Factory Pattern)
立即学习“go语言免费学习笔记(深入)”;
简单工厂模式的核心是一个工厂函数或方法,它根据传入的参数来决定创建并返回哪种具体的产品实例。
假设我们正在开发一个游戏,需要创建不同类型的角色(比如战士、法师)。
package main
import "fmt"
// Character 是产品接口
type Character interface {
Attack() string
Defend() string
}
// Warrior 是具体产品
type Warrior struct{}
func (w *Warrior) Attack() string {
return "战士挥舞大剑,造成物理伤害!"
}
func (w *Warrior) Defend() string {
return "战士举起盾牌,格挡攻击!"
}
// Mage 是具体产品
type Mage struct{}
func (m *Mage) Attack() string {
return "法师吟唱咒语,释放魔法攻击!"
}
func (m *Mage) Defend() string {
return "法师施展护盾,抵御伤害!"
}
// SimpleCharacterFactory 是简单工厂,根据类型创建角色
func SimpleCharacterFactory(charType string) Character {
switch charType {
case "warrior":
return &Warrior{}
case "mage":
return &Mage{}
default:
fmt.Println("未知角色类型,返回默认战士")
return &Warrior{} // 或者返回nil,或者报错
}
}
// func main() {
// warrior := SimpleCharacterFactory("warrior")
// fmt.Println(warrior.Attack())
// fmt.Println(warrior.Defend())
// mage := SimpleCharacterFactory("mage")
// fmt.Println(mage.Attack())
// fmt.Println(mage.Defend())
// // 尝试创建不存在的类型
// unknown := SimpleCharacterFactory("rogue")
// fmt.Println(unknown.Attack())
// }抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式则更复杂一些,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。可以理解为“工厂的工厂”。
继续游戏开发的例子,现在我们不仅有角色,还有武器和防具,并且这些物品是分“阵营”的,比如“光明阵营”和“黑暗阵营”,每个阵营都有自己的战士、法师,以及对应的武器和防具。
package main
import "fmt"
// --- 产品接口 ---
type Character interface {
Info() string
}
type Weapon interface {
Damage() string
}
type Armor interface {
Defense() string
}
// --- 光明阵营具体产品 ---
type LightWarrior struct{}
func (lw *LightWarrior) Info() string { return "光明战士" }
type LightMage struct{}
func (lm *LightMage) Info() string { return "光明法师" }
type LightSword struct{}
func (ls *LightSword) Damage() string { return "光明之剑造成圣光伤害" }
type LightRobe struct{}
func (lr *LightRobe) Defense() string { return "光明法袍提供神圣防御" }
// --- 黑暗阵营具体产品 ---
type DarkWarrior struct{}
func (dw *DarkWarrior) Info() string { return "黑暗战士" }
type DarkMage struct{}
func (dm *DarkMage) Info() string { return "黑暗法师" }
type DarkAxe struct{}
func (da *DarkAxe) Damage() string { return "黑暗战斧造成腐蚀伤害" }
type DarkPlate struct{}
func (dp *DarkPlate) Defense() string { return "黑暗板甲提供暗影防御" }
// --- 抽象工厂接口 ---
type GameFactory interface {
CreateWarrior() Character
CreateMage() Character
CreateWeapon() Weapon
CreateArmor() Armor
}
// --- 光明阵营具体工厂 ---
type LightFactory struct{}
func (lf *LightFactory) CreateWarrior() Character { return &LightWarrior{} }
func (lf *LightFactory) CreateMage() Character { return &LightMage{} }
func (lf *LightFactory) CreateWeapon() Weapon { return &LightSword{} }
func (lf *LightFactory) CreateArmor() Armor { return &LightRobe{} }
// --- 黑暗阵营具体工厂 ---
type DarkFactory struct{}
func (df *DarkFactory) CreateWarrior() Character { return &DarkWarrior{} }
func (df *DarkFactory) CreateMage() Character { return &DarkMage{} }
func (df *DarkFactory) CreateWeapon() Weapon { return &DarkAxe{} }
func (df *DarkFactory) CreateArmor() Armor { return &DarkPlate{} }
// func main() {
// // 创建光明阵营的物品
// lightFactory := &LightFactory{}
// lightWarrior := lightFactory.CreateWarrior()
// lightWeapon := lightFactory.CreateWeapon()
// lightArmor := lightFactory.CreateArmor()
// fmt.Printf("创建了: %s, 武器: %s, 防具: %s\n", lightWarrior.Info(), lightWeapon.Damage(), lightArmor.Defense())
// // 创建黑暗阵营的物品
// darkFactory := &DarkFactory{}
// darkMage := darkFactory.CreateMage()
// darkWeapon := darkFactory.CreateWeapon()
// darkArmor := darkFactory.CreateArmor()
// fmt.Printf("创建了: %s, 武器: %s, 防具: %s\n", darkMage.Info(), darkWeapon.Damage(), darkArmor.Defense())
// }简单工厂模式在Go语言中落地非常直观,通常表现为一个返回接口类型的函数。这个函数内部包含一个
switch
map
实现要点:
适用场景:
我个人觉得,简单工厂模式最适合那些创建逻辑相对简单,且产品种类不多的情况。
LoadConfigParser(type string)
&Struct{}优点:
缺点:
抽象工厂模式在Go语言中实现时,同样离不开接口。它比简单工厂更抽象一层,引入了“工厂的工厂”的概念。
实现要点:
Character
Weapon
Armor
LightWarrior
DarkWarrior
CreateWarrior()
CreateWeapon()
LightFactory
与简单工厂的主要区别:
在我看来,最核心的区别在于它们关注的粒度和解决的问题:
new
举个例子,简单工厂可能帮你创建“一个”数据库连接(MySQL或PostgreSQL),而抽象工厂则可能帮你创建“一套”与数据库相关的对象(MySQL连接、MySQL查询构建器、MySQL事务管理器),并且这些对象都是为MySQL设计的。
优点:
缺点:
Mount
选择简单工厂还是抽象工厂,这真是一个“看菜下碟”的问题,没有绝对的答案。我通常会根据项目的规模、复杂性以及未来的可扩展性需求来权衡。
选择简单工厂的考量:
选择抽象工厂的考量:
两者间的取舍:
我通常是这样思考的:
map[string]func() interface{}最终,选择哪种模式,取决于你对当前和未来需求的判断。没有银弹,只有最适合你当前场景的工具。
以上就是怎样用Golang实现工厂模式 对比简单工厂与抽象工厂区别的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号