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