Search code examples
syntaxgogo-interface

Object Factory in golang


I am a new to golang. I need to design a function to create object of differing types based on input. But I failed to figure out how to design the interface. Here comes my code:

package main

import (
    "fmt"
)

type AA struct{
    name string
}

func (this *AA) say(){
    fmt.Println("==========>AA")
}
type BB struct{
    *AA
    age int
}
func (this *BB) say(){
    fmt.Println("==========>BB")
}

func ObjectFactory(type int) *AA {
    if type ==1 {
        return new(AA)
    }else{
        return new(BB)
    }
}

func main() {
    obj1 := ObjectFactory(0)
    obj1.say()
    obj2 := ObjectFactory(0)
    obj2.say()
}

The compiler tells me error no matter I ask ObjectFactory return *AA or interface{}. How can I make it work?


Solution

  • First off, using type as a variable name is disallowed in go (see the spec). That is your first problem.

    The return type of object factory is *AA. This means that it can only return variables of type *AA, which causes the return of type of BB to fail. As defined in the spec, go doesn't have type inheritance, just struct embedding.

    If you create an interface called sayer, you can use that instead of *AA in your ObjectFactory function.

    type sayer interface {
        say()
    }
    

    You probably want to use this interface when trying to get multiple dispatch (as demonstrated in the code below (see on play.golang.org as well).

    Try this code:

    package main
    
    import (
        "fmt"
    )
    
    type sayer interface {
        say()
    }
    
    type AA struct{
        name string
    }
    
    func (this *AA) say(){
        fmt.Println("==========>AA")
    }
    type BB struct{
        *AA
        age int
    }
    func (this *BB) say(){
        fmt.Println("==========>BB")
    }
    
    func ObjectFactory(typeNum int) sayer {
        if typeNum ==1 {
            return new(AA)
        }else{
            return new(BB)
        }
    }
    
    func main() {
        obj1 := ObjectFactory(1)
        obj1.say()
        obj2 := ObjectFactory(0)
        obj2.say()
    }