之前我们介绍了工厂,现在我们再看一下抽象工厂设计模式。抽象工程模式顾名思义就是对工厂模式的一层抽象,也是创建型模式的一种,通常用来创建一组存在相关性的对象。

UML类图大致如下:

GoLang设计模式03 - 抽象工厂模式

类图比较复杂,最好用个例子来说明。比方说,国内有两家生产运动服的工厂:nike和adidas 。现在我们想购买一套运动服,包含短裤(short)和运动鞋(shoe)。通常我们都会在同一家工厂购买整套的运动服。这时抽象工厂模式就可以发挥作用了。

现在我们需要的产品有两种:短裤(short)和运动鞋(shoe)。

生产这些产品的工厂有两家:nike和adidas。

iSportsFactory

然后,我们还要为具体的产品定义两个接口:

iShortnikeShortadidasShortiShoenikeShoeadidasShoe

看下具体的代码:

iSportsFactory.go

packagemainimport"fmt"typeiSportsFactory interface{    makeShoe() iShoe    makeShort() iShort}funcgetSportsFactory(brand string) (iSportsFactory, error) {    ifbrand == "adidas"{        return&adidas{}, nil    }    ifbrand == "nike"{        return&nike{}, nil    }    returnnil, fmt.Errorf("Wrong brand type passed")}

  iShort.go

packagemaintypeiShort interface{    setLogo(logo string)    setSize(size int)    getLogo() string    getSize() int}typeshort struct{    logo string    size int}func(s *short) setLogo(logo string) {    s.logo = logo}func(s *short) getLogo() string {    returns.logo}func(s *short) setSize(size int) {    s.size = size}func(s *short) getSize() int {    returns.size}

  iShoe.go

packagemaintypeiShoe interface{    setLogo(logo string)    setSize(size int)    getLogo() string    getSize() int}typeshoe struct{    logo string    size int}func(s *shoe) setLogo(logo string) {    s.logo = logo}func(s *shoe) getLogo() string {    returns.logo}func(s *shoe) setSize(size int) {    s.size = size}func(s *shoe) getSize() int {    returns.size}

  nike.go

packagemaintypenike struct{}typenikeShoe struct{    shoe}typenikeShort struct{    short}func(n *nike) makeShoe() iShoe {    return&nikeShoe{        shoe: shoe{            logo: "nike",            size: 14,        },    }}func(n *nike) makeShort() iShort {    return&nikeShort{        short: short{            logo: "nike",            size: 14,        },    }}

  adidas.go

packagemaintypeadidas struct{}typeadidasShoe struct{    shoe}typeadidasShort struct{    short}func(a *adidas) makeShoe() iShoe {    return&adidasShoe{        shoe: shoe{            logo: "adidas",            size: 14,        },    }}func(a *adidas) makeShort() iShort {    return&adidasShort{        short: short{            logo: "adidas",            size: 14,        },    }}

  main.go

packagemainimport"fmt"funcmain() {    adidasFactory, _ := getSportsFactory("adidas")    nikeFactory, _ := getSportsFactory("nike")    nikeShoe := nikeFactory.makeShoe()    nikeShort := nikeFactory.makeShort()    adidasShoe := adidasFactory.makeShoe()    adidasShort := adidasFactory.makeShort()    printShoeDetails(nikeShoe)    printShortDetails(nikeShort)    printShoeDetails(adidasShoe)    printShortDetails(adidasShort)}funcprintShoeDetails(s iShoe) {    fmt.Printf("Logo: %s", s.getLogo())    fmt.Println()    fmt.Printf("Size: %d", s.getSize())    fmt.Println()}funcprintShortDetails(s iShort) {    fmt.Printf("Logo: %s", s.getLogo())    fmt.Println()    fmt.Printf("Size: %d", s.getSize())    fmt.Println()}

End!