Go 抽象工厂模式讲解和代码示例

简介: Go 抽象工厂模式讲解和代码示例

抽象工厂是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

抽象工厂定义了用于创建不同产品的接口 但将实际的创建工作留给了具体工厂类 每个工厂类型都对应一个特定的产品变体

在创建产品时 客户端代码调用的是工厂对象的构建方法 而不是直接调用构造函数 new操作符 由于一个工厂对应一种产品变体 因此它创建的所有产品都可相互兼容

客户端代码仅通过其抽象接口与工厂和产品进行交互 该接口允许同一客户端代码与不同产品进行交互 你只需创建一个具体工厂类并将其传递给客户端代码即可

概念示例

让我们假设一下 如果你想要购买一组运动装备 比如一双鞋与一件衬衫这样由两种不同产品组合而成的套装 相信你会想去购买同一品牌的商品 这样商品之间能够互相搭配起来

如果我们把这样的行为转换成代码的话 帮助我们创建此类产品组的工具就是抽象工厂 便于产品之间能够相互匹配

iSportsFactory.go: 抽象工厂接口

package main
import "fmt"
type iSportsFactory interface {
    makeShoe() iShoe
    makeShirt() iShirt
}
func getSportsFactory(brand string) (iSportsFactory, error) {
    if brand == "adidas" {
        return &adidas{}, nil
    }
    if brand == "nike" {
        return &nike{}, nil
    }
    return nil, fmt.Errorf("Wrong brand type passed")
}
 adidas.go: 具体工厂
package main
type adidas struct {
}
func (a *adidas) makeShoe() iShoe {
    return &adidasShoe{
        shoe: shoe{
            logo: "adidas",
            size: 14,
        },
    }
}
func (a *adidas) makeShirt() iShirt {
    return &adidasShirt{
        shirt: shirt{
            logo: "adidas",
            size: 14,
        },
    }
}

nike.go: 具体工厂

package main
type nike struct {
}
func (n *nike) makeShoe() iShoe {
    return &nikeShoe{
        shoe: shoe{
            logo: "nike",
            size: 14,
        },
    }
}
func (n *nike) makeShirt() iShirt {
    return &nikeShirt{
        shirt: shirt{
            logo: "nike",
            size: 14,
        },
    }
}

iShoe.go: 抽象产品

package main
type iShoe interface {
    setLogo(logo string)
    setSize(size int)
    getLogo() string
    getSize() int
}
type shoe struct {
    logo string
    size int
}
func (s *shoe) setLogo(logo string) {
    s.logo = logo
}
func (s *shoe) getLogo() string {
    return s.logo
}
func (s *shoe) setSize(size int) {
    s.size = size
}
func (s *shoe) getSize() int {
    return s.size
}

adidasShoe.go: 具体产品

package main
type adidasShoe struct {
    shoe
}

nikeShoe.go: 具体产品

package main
type nikeShoe struct {
    shoe
}

iShirt.go: 抽象产品

package main
type iShirt interface {
    setLogo(logo string)
    setSize(size int)
    getLogo() string
    getSize() int
}


type shirt struct {
    logo string
    size int
}
func (s *shirt) setLogo(logo string) {
    s.logo = logo
}
func (s *shirt) getLogo() string {
    return s.logo
}
func (s *shirt) setSize(size int) {
    s.size = size
}
func (s *shirt) getSize() int {
    return s.size
}

adidasShirt.go: 具体产品

package main
type adidasShirt struct {
    shirt
}

nikeShirt.go: 具体产品

package main
type nikeShirt struct {
    shirt
}

main.go: 客户端代码

package main
import "fmt"
func main() {
    adidasFactory, _ := getSportsFactory("adidas")
    nikeFactory, _ := getSportsFactory("nike")
    nikeShoe := nikeFactory.makeShoe()
    nikeShirt := nikeFactory.makeShirt()
    adidasShoe := adidasFactory.makeShoe()
    adidasShirt := adidasFactory.makeShirt()
    printShoeDetails(nikeShoe)
    printShirtDetails(nikeShirt)
    printShoeDetails(adidasShoe)
    printShirtDetails(adidasShirt)
}
func printShoeDetails(s iShoe) {
    fmt.Printf("Logo: %s", s.getLogo())
    fmt.Println()
    fmt.Printf("Size: %d", s.getSize())
    fmt.Println()
}
func printShirtDetails(s iShirt) {
    fmt.Printf("Logo: %s", s.getLogo())
    fmt.Println()
    fmt.Printf("Size: %d", s.getSize())
    fmt.Println()
}

output.txt: 执行结果

Logo: nike
Size: 14
Logo: nike
Size: 14
Logo: adidas
Size: 14
Logo: adidas
Size: 14
相关文章
|
5月前
|
Cloud Native Go 开发工具
不改一行代码轻松玩转 Go 应用微服务治理
为了更好的进行 Go 应用微服务治理,提高研发效率和系统稳定性,本文将介绍 MSE 微服务治理方案,无需修改业务代码,实现治理能力。
19881 17
|
2月前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
387 1
|
7月前
|
算法 程序员 编译器
美丽的代码:规范go应用代码注释
【6月更文挑战第30天】本文介绍注释应与代码同步,避免误导,且关键点解释。使用LLVM构建编译器示例展示Go语言规范。注释虽有局限,但在解释复杂逻辑、业务规则时仍有其价值。程序员需平衡注释与代码的关系,创造更优的代码。
1104 0
美丽的代码:规范go应用代码注释
|
2月前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
43 2
|
2月前
|
SQL 监控 算法
为Go应用无侵入地添加任意代码
这篇文章旨在提供技术深度和实践指南,帮助开发者理解并应用这项创新技术来提高Golang应用的监控与服务治理能力。在接下来的部分,我们将通过一些实际案例,进一步展示如何在不同场景中应用这项技术,提供更多实践启示。
|
4月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
3月前
|
JSON 搜索推荐 Go
ZincSearch搜索引擎中文文档及在Go语言中代码实现
ZincSearch官网及开发文档均为英文,对非英语用户不够友好。GoFly全栈开发社区将官方文档翻译成中文,并增加实战经验和代码,便于新手使用。本文档涵盖ZincSearch在Go语言中的实现,包括封装工具库、操作接口、统一组件调用及业务代码示例。官方文档https://zincsearch-docs.zinc.dev;中文文档https://doc.goflys.cn/docview?id=41。
141 0
|
5月前
|
缓存 NoSQL 数据库
go-zero微服务实战系列(五、缓存代码怎么写)
go-zero微服务实战系列(五、缓存代码怎么写)
|
5月前
|
程序员 测试技术 Go
用 Go 编写简洁代码的最佳实践
用 Go 编写简洁代码的最佳实践
|
5月前
|
缓存 测试技术 Go
使用Singleflight优化Go代码
使用Singleflight优化Go代码