[03]Go设计模式:工厂模式(Factory Pattern)

工厂模式

一、简介

工厂模式(Factory Pattern)是软件设计中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。在每增加一种类型时,只需要修改工厂函数即可。 在产品较多时,工厂函数代码逻辑将会非常复杂。

二、代码

package main

import "fmt"

type Animal interface {
    CanFly() bool
}

type Dog struct {
    Name string
    Age  int
}

func NewDog(name string, age int) *Dog {
    return &Dog{
        Name: name,
        Age:  age,
    }
}

func(d *Dog)CanFly() bool{
    fmt.Printf("%s can not fly\n", d.Name)
    return false
}

type Cat struct {
    Name string
    Age  int
}

func NewCat(name string, age int) *Cat {
    return &Cat{
        Name: name,
        Age:  age,
    }
}

func(c *Cat)CanFly() bool{
    fmt.Printf("%s can not fly\n", c.Name)
    return false
}

func Factory(name string, age int) Animal {
    if name == "Cat" {
        return NewCat(name, age)
    }else{
        return NewDog(name, age)
    }
}

func main(){
    d1 := Factory("Dog", 1)
    d1.CanFly()
    c1 := Factory("Cat", 1)
    c1.CanFly()
}

在写Factory遇到一个问题:

package main

import "fmt"

type Animal interface {
    CanFly() bool
}

type Cat struct {
    Name string
    Age  int
}

func NewCat(name string, age int) Cat {
    return Cat{
        Name: name,
        Age:  age,
    }
}

func(c *Cat)CanFly() bool{
    //修改只需要将c *Cat修改为c Cat即可
    fmt.Printf("%s can not fly\n", c.Name)
    return false
}

func Factory(name string, age int) Animal {
    if name == "Cat" {
        return NewCat(name, age) //这一行一直报错
    }
    return nil
}

method has pointer receiver, 通过参考资料2的链接解决了问题。一个struct虽然可以通过值类型和引用类型两种方式定义方法,但是不通的对象类型对应了不同的方法集:

Values Methods Receivers
T (t T)
*T (t T) and (t *T)

值类型的对象只有(t T) 结构的方法,虽然值类型的对象也可以调用(t *T) 方法,但这实际上是Golang编译器自动转化成了&t的形式来调用方法,并不是表明值类型的对象拥有该方法。

换一个维度来看上面的表格可能更加直观:

Values Methods Receivers
(t T) T and *T
(t *T) *T

这就意味着指针类型的receiver 方法实现接口时,只有指针类型的对象实现了该接口。

三、参考资料

1、 https://www.runoob.com/design-pattern/factory-pattern.html

2、 https://stackoverflow.com/questions/33936081/golang-method-with-pointer-receiver

猜你喜欢

转载自www.cnblogs.com/0pandas0/p/12040421.html