Mocking single methods in Go - testing

In Go, how can I mock an interface without having to implement every method? Let's say I have a Car interface and a Corolla struct that implements that interface:
type Car interface {
changeTire()
startEngine()
....
refuel()
}
type Corolla struct {
...
}
func (c Corolla) changeTire() {...}
func (c Corolla) startEngine() {...}
func (c Corolla) refuel() {...}
Let's say I also have a Garage struct that depends on Car:
type Garage struct {
MyCar Car
}
func (g Garage) PrepareCarToDrive() {
g.MyCar.changeTire()
g.MyCar.refuel()
g.MyCar.startEngine()
}
And I want to test Garage, so I create a MockCar that implements Car
type MockCar struct {
...
}
func (c MockCar) changeTire() {...}
func (c MockCar) startEngine() {...}
func (c MockCar) refuel() {...}
Now I have tests that test PrepareCarToDrive and I use the MockCar:
func TestGarage_PrepareCarToDrive_DoesSomething(t *testing.T) {
mockCar := MockCar{}
garageUnderTest := Garage{}
garageUnderTest.MyCar = mockCar
// some other setup
// when Garage calls mockCar.changeTire(), should do X
...
}
func TestGarage_PrepareCarToDrive_DoesSomethingElse(t *testing.T) {
mockCar := MockCar{}
garageUnderTest := Garage{}
garageUnderTest.MyCar = mockCar
// some other setup
// when Garage calls mockCar.changeTire(), should do Y
...
}
My question is, how can I have mockCar do different things each test? I know that I can create a different mock implementation of Car for each test. But this will get out of hand really quickly as I add more methods to Car.
I'm coming from a Java background so I'm looking for something like Mockito that will let me mock just the methods I need for each test.
What is the best way to do this in Go? Or am I missing something more fundamental?

If you embed the interface type itself in your mock struct, you can then only implement the methods you need. For example:
type MockCar struct {
Car
...
}
func (c MockCar) changeTire() {...}
Even though your struct only implements changeTire explicitly, it still satisfies the interface because the Car field provides the rest. This works as long as you don't try to call any of the unimplemented methods (which will cause a panic because Car is nil)

The easiest method is to use some base implementation as an embed for your test structure, and only override the method you're testing. Example using your types:
type MockCar struct {
Corolla // embedded, so the method implementations of Corolla get promoted
}
// overrides the Corolla implementation
func (c MockCar) changeTire() {
// test stuff
}
// refuel() and startEngine(), since they are not overridden, use Corolla's implementation
https://play.golang.org/p/q3_L1jf4hk
An alternative, if you need a different implementation per test, is to use a mock with function fields:
type MockCar struct {
changeTireFunc func()
startEngineFunc func()
....
refuelFunc func()
}
func (c MockCar) changeTire() {
if c.changeTireFunc != nil {
c.changeTireFunc()
}
}
func (c MockCar) startEngine() {
if c.startEngineFunc != nil {
c.startEngineFunc()
}
}
func (c MockCar) refuel() {
if c.refuelFunc != nil {
c.refuelFunc()
}
}
// test code
func TestGarage_PrepareCarToDrive_DoesSomething(t *testing.T) {
// let's say we require refuel(), but the default implementation is fine
// changeTire(), however, requires a mocked testing implementation
// and we don't need startEngine() at all
mockCar := MockCar{
changeTireFunc: func() {
// test functionality
},
refuelFunc: Corolla.refuel,
}
garageUnderTest := Garage{}
garageUnderTest.MyCar = mockCar
// some other setup
// when Garage calls mockCar.changeTire(), should do X
...
}
https://play.golang.org/p/lf7ny-lUCS
This style is a bit less useful when you're trying to use another type's methods as the default implementation, but can be very useful if you have some stand-alone functions that can be used as your default or test implementation, or if a trivial return is acceptable for functions you haven't specifically mocked (like the behavior of the mocked startEngine() in the example above, which does nothing at all when called because the startEngineFunc field is nil).
You can also, if you wish, bake the default implementation (like a call to (Corolla{}).startEngine()) into the mock method if the relevant function field is nil. This allows you the best of both worlds, with a default non-trivial implementation and the ability to hotswap out implementations at will on the mock just by changing the relevant function field.

Related

How to implement an interface with functions sharing the same logic?

I'd like to provide multiple implementations for the following interface:
type API interface {
A()
B()
C()
}
According to my use cases, all implementations should share the exact same logic for function A and B while function C will have different logic for different implementations.
So I've created the following common implementation to be embedded:
type Common struct {}
func (c *Common) A() {}
func (c *Common) B() {}
To create two implementations for the interface above, I can just do the following:
type FirstImpl struct { Common }
func (i *FirstImpl) C() {}
type SecondImpl struct { Common }
func (i *SecondImpl) C() {}
Everything works just fine until I find out that function C needs to be called inside function B. Note that the logic for function B should still be the same across two implementations despite that we may get different results calling C inside B.
I'm wondering if this is a common pattern in Go and if there is an elegant way to handle it.
You want to emulate late binding.
One way to achieve this is by using a function pointer, and constructors for implementations:
type CommonImpl struct {
cimpl func()
}
func (c CommonImpl) C() { c.cimpl() }
type FirstImpl struct {
CommonImpl
}
func NewFirstImpl() APIImpl {
ret:=FirstImpl{}
ret.cimpl=ret.c
return &ret
}
With this implementation, you can call the derived-type C().
An alternative would be to pass the function as an argument:
func (c CommonImpl) C(bfunc func()) {
}
...
x:=FirstImpl{}
x.C(x.B)
Or with an interface:
type BIntf interface {
B()
}
func (c CommonImpl) C(b BIntf) {
}
x:=FirstImpl{}
x.C(x)

Polymorphism in Golang

It's simple example what I want:
I have object of B and use function step1 from struct A (common functionality). I need to redefine function step2 for B which runs inside A.
package main
import "fmt"
type A struct {}
func (a *A) step1() {
a.step2();
}
func (a *A) step2 () {
fmt.Println("get A");
}
type B struct {
A
}
func (b *B) step2 () {
fmt.Println("get B");
}
func main() {
obj := B{}
obj.step1()
}
How can I do it?
// maybe
func step1(a *A) {
self.step2(a);
}
Go doesn't do polymorphism. You have to recast what you want to do in terms of interfaces, and functions (not methods) that take those interfaces.
So think what interface does each object need to satisfy, then what functions you need to work on that interface. There are lots of great examples in the go standard library, eg io.Reader, io.Writer and the functions which work on those, eg io.Copy.
Here is my attempt to recast your example into that style. It doesn't make a lot of sense, but hopefully it will give you something to work on.
package main
import "fmt"
type A struct {
}
type steps interface {
step1()
step2()
}
func (a *A) step1() {
fmt.Println("step1 A")
}
func (a *A) step2() {
fmt.Println("get A")
}
type B struct {
A
}
func (b *B) step2() {
fmt.Println("get B")
}
func step1(f steps) {
f.step1()
f.step2()
}
func main() {
obj := B{}
step1(&obj)
}

How to implement an abstract class in Go?

How to implement an abstract class in Go? As Go doesn't allow us to have fields in interfaces, that would be a stateless object. So, in other words, is it possible to have some kind of default implementation for a method in Go?
Consider an example:
type Daemon interface {
start(time.Duration)
doWork()
}
func (daemon *Daemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
daemon.doWork()
}
}()
}
type ConcreteDaemonA struct { foo int }
type ConcreteDaemonB struct { bar int }
func (daemon *ConcreteDaemonA) doWork() {
daemon.foo++
fmt.Println("A: ", daemon.foo)
}
func (daemon *ConcreteDaemonB) doWork() {
daemon.bar--
fmt.Println("B: ", daemon.bar)
}
func main() {
dA := new(ConcreteDaemonA)
dB := new(ConcreteDaemonB)
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
time.Sleep(100 * time.Second)
}
This won't compile as it's not possible to use interface as a receiver.
In fact, I have already answered my question (see the answer below). However, is it an idiomatic way to implement such logic? Are there any reasons not to have a default implementation besides language's simplicity?
The other answers provide an alternative to your problem, however they proposed solution without using abstract classes/struct, and I guess if you were interested in using abstract class like solution, here is very precise solution to your problem:
Go plaground
package main
import (
"fmt"
"time"
)
type Daemon interface {
start(time.Duration)
doWork()
}
type AbstractDaemon struct {
Daemon
}
func (a *AbstractDaemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
a.doWork()
}
}()
}
type ConcreteDaemonA struct {
*AbstractDaemon
foo int
}
func newConcreteDaemonA() *ConcreteDaemonA {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonA{a, 0}
a.Daemon = r
return r
}
type ConcreteDaemonB struct {
*AbstractDaemon
bar int
}
func newConcreteDaemonB() *ConcreteDaemonB {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonB{a, 0}
a.Daemon = r
return r
}
func (a *ConcreteDaemonA) doWork() {
a.foo++
fmt.Println("A: ", a.foo)
}
func (b *ConcreteDaemonB) doWork() {
b.bar--
fmt.Println("B: ", b.bar)
}
func main() {
var dA Daemon = newConcreteDaemonA()
var dB Daemon = newConcreteDaemonB()
dA.start(1 * time.Second)
dB.start(5 * time.Second)
time.Sleep(100 * time.Second)
}
If this is still not obvious how to use abstract classes/multi-inheritance in go-lang here is the post with comprehensive details. Abstract Classes In Go
If you want to provide a "default" implementation (for Daemon.start()), that is not the characteristic of an interface (at least not in Go). That is a characteristic of a concrete (non-interface) type.
So Daemon in your case should be a concrete type, conveniently a struct since you want it to have fields. And the task to be done can be either a value of an interface type, or in a simple case just a function value (a simple case means it would only have one method).
With interface type
Try the complete app on the Go Playground.
type Task interface {
doWork()
}
type Daemon struct {
task Task
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task.doWork() periodically
go func() {
for {
<-ticker.C
d.task.doWork()
}
}()
}
type MyTask struct{}
func (m MyTask) doWork() {
fmt.Println("Doing my work")
}
func main() {
d := Daemon{task: MyTask{}}
d.start(time.Millisecond*300)
time.Sleep(time.Second * 2)
}
With a function value
In this simple case this one is shorter. Try it on the Go Playground.
type Daemon struct {
task func()
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task() periodically
go func() {
for {
<-ticker.C
d.task()
}
}()
}
func main() {
d := Daemon{task: func() {
fmt.Println("Doing my work")
}}
d.start(time.Millisecond * 300)
time.Sleep(time.Second * 2)
}
An easy solution is to move daemon *Daemon to the argument list (thus removing start(...) from the interface):
type Daemon interface {
// start(time.Duration)
doWork()
}
func start(daemon Daemon, duration time.Duration) { ... }
func main() {
...
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
...
}
You can implement abstract class in go.
The definition:
type abstractObject interface{
print()
}
type object struct{
a int
abstractObject
}
Now object is an abstract class, like java's.
You can inherit it and use its members:
type concreteObject struct{
*object
}
(o *concreteObject) print() {
fmt.Println(o.a)
}
func newConcreteObject(o *object) {
obj := &concreteObject{object: o}
o.abstractObject = obj // all magics are in this statement.
}
And use the object with concreteObject's methods:
o := &object{}
newConcereteObject(o)
o.print()
And cast abstract object to concrete object:
concObj := o.abstractObject.(*concreteObject)
Just like other OOP languages.
The solution by Max Malysh would work in some cases if you don't need a factory. However the solution given by Adrian Witas could cause cyclic dependencies issues.
This is the way I achieved implementing an abstract class the easy way respecting cyclic dependencies and good factory patterns.
Let us assume we have the following package structure for our component
component
base
types.go
abstract.go
impl1
impl.go
impl2
impl.go
types.go
factory.go
Define the definition of the component, in this example it will be defined here:
component/types.go
package component
type IComponent interface{
B() int
A() int
Sum() int
Average() int
}
Now let's assume we want to create an abstract class that implements Sum and Average only, but in this abstract implementation we would like to have access to use the values returned by the implemented A and B
To achieve this, we should define another interface for the abstract members of the abstract implementation
component/base/types.go
package base
type IAbstractComponentMembers {
A() int
B() int
}
And then we can proceed to implement the abstract "class"
component/base/abstract.go
package base
type AbstractComponent struct {
IAbstractComponentsMember
}
func (a *AbstractComponent) Sum() int {
return a.A() + a.B()
}
func (a *AbstractComponent) Average() int {
return a.Sum() / 2
}
And now we proceed to the implementations
component/impl1/impl.go // Asume something similar for impl2
package impl1
type ComponentImpl1 struct {
base.AbstractComponent
}
func (c *ComponentImpl1) A() int {
return 2
}
func (c *ComponentImpl1) A() int {
return 4
}
// Here is how we would build this component
func New() *ComponentImpl1 {
impl1 := &ComponentImpl1{}
abs:=&base.AbstractComponent{
IAbstractComponentsMember: impl1,
}
impl1.AbstractComponent = abs
return impl1
}
The reason we use a separate interface for this instead of using Adrian Witas example, is because if we use the same interface in this case, if we import the base package in impl* to use the abstract "class" and also we import the impl* packages in the components package, so the factory can register them, we'll find a circular reference.
So we could have a factory implementation like this
component/factory.go
package component
// Default component implementation to use
const defaultName = "impl1"
var instance *Factory
type Factory struct {
// Map of constructors for the components
ctors map[string]func() IComponent
}
func (f *factory) New() IComponent {
ret, _ := f.Create(defaultName)
return ret
}
func (f *factory) Create(name string) (IComponent, error) {
ctor, ok := f.ctors[name]
if !ok {
return nil, errors.New("component not found")
}
return ctor(), nil
}
func (f *factory) Register(name string, constructor func() IComponent) {
f.ctors[name] = constructor
}
func Factory() *Factory {
if instance == nil {
instance = &factory{ctors: map[string]func() IComponent{}}
}
return instance
}
// Here we register the implementations in the factory
func init() {
Factory().Register("impl1", func() IComponent { return impl1.New() })
Factory().Register("impl2", func() IComponent { return impl2.New() })
}
The functionality of abstract class has below requirements
1. It should not be possible to create direct instance of abstract class
2. It should provide default fields and methods.
A combination of interface and struct can be used to fulfill above two requirements. For example we can see below
package main
import "fmt"
//Abstract Interface
type iAlpha interface {
work()
common(iAlpha)
}
//Abstract Concrete Type
type alpha struct {
name string
}
func (a *alpha) common(i iAlpha) {
fmt.Println("common called")
i.work()
}
//Implementing Type
type beta struct {
alpha
}
func (b *beta) work() {
fmt.Println("work called")
fmt.Printf("Name is %s\n", b.name)
}
func main() {
a := alpha{name: "test"}
b := &beta{alpha: a}
b.common(b)
}
Output:
common called
work called
Name is test
One important point to mention here is that all default method should have iAlpha as first argument, and if default method needs to call any unimplemented method they they will call on this interface. This is same as we did in common method above - i.work().
Source: https://golangbyexample.com/go-abstract-class/

testing non returning method in go

I have a simple method, which just checks if a parameter is empty and then calls one of 2 methods based on a struct field.
How would I test it?
func (cT *customType) someMethod(message string) {
if message == ""{
return
}
if cT.value == nil {
cT.doFunctionOne()
} else {
cT.doFunctionTwo()
}
}
In Javascript, I would create a spy on doFunctionOne() and mock up the object.
Mocking up works well in Go as well, but how would I do the 'spying' part?
Or is there another idiomatic way to test this kind of method?
First: You wouldn't name a method "doFunctionOne" but "methodOne" :-)
If neither doFunctionOne nor doFunctionTwo has any observable effect, then there is absolutely no point in testing it. So we may assume that they do have observable side effect, either on the environment or on the customType they have been invoked on.
Now just test these side effects. This is trivial if both methods do return. If they spin up an endless loop it becomes harder, but still doable.
IMHO there is no need to "test" this method in the sense of "test whether it calls One or Two depending on value": For me this is to lowlevel, too much increasing coverage count for nothing. If you call some method it has to do something (observable effect) and you should check this effect, not the inner workings.
The idiomatic way of mocking an object in Go is to make it explicit. A healthy interface should be testable by itself. So if we have something like this:
type customType struct {
value int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) someMethod() {
if c.value <= 0 {
c.doFunctionOne()
} else {
c.doFunctionTwo()
}
}
We have to provide a way to change the implementation of doFunctionOne and doFunctionTwo explicitly. We can generalize the someMethod behavior using interfaces:
type customType struct {
myValue int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) value() int {
return c.myValue
}
type Interface interface {
value() int
doFunctionOne()
doFunctionTwo()
}
func someMethod(i Interface) {
if i.value() <= 0 {
i.doFunctionOne()
} else {
i.doFunctionTwo()
}
}
type customTestingType struct {
t *testing.T
}
func (c customTestingType) doFunctionOne() {
c.t.Log("Working")
}
func (c customTestingType) doFunctionTwo() {
c.t.Error("Not working")
}
func (c customTestingType) value() int {
return 0
}
func TestInterface(t *testing.T) {
someMethod(customTestingType{t})
}
Surely there will be more ways to provide this behavior but it depends on the particular declaration of your type. As an example, you can look at httptest package. That said, if you really want to mock your type in that way (nonidiomatic), you can some unsafe monkey patching:
package main
import (
"fmt"
"reflect"
"github.com/bouk/monkey"
)
type customType struct {
myValue int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) someMethod() {
if c.myValue <= 0 {
c.doFunctionOne()
} else {
c.doFunctionTwo()
}
}
func main() {
c := customType{0}
monkey.PatchInstanceMethod(reflect.TypeOf(c), "doFunctionOne",
func(c customType) {
fmt.Println("Method #1, but patched")
})
monkey.PatchInstanceMethod(reflect.TypeOf(c), "doFunctionTwo",
func(c customType) {
fmt.Println("Method #2, but patched")
})
c.someMethod()
}
You can add log before each function call.
Inject your own logger implementation, []string for example.
Check the string slice for a matching strings.
But, if you are creating a function factory it would be better if you return the function to the caller and the caller will run the function.
Then testing is straightforward.
Second but, there is only two kind of functions, flow function and logic functions.
You mixed flow and logic in the same function.
Testing difficulty is just one symptom of this bad practice.

is it possible to call overridden method from parent struct in Golang?

I want to implement such code, where B inherit from A and only override A's Foo() method, and I hope the code to print B.Foo(), but it still print A.Foo(), it seems that the receiver in Golang can't work like this in C++, in which when dynamic binding is enabled, the code can work like what I want.
I also post another piece of code, which works, but it's too hard to implement, and more like a hack way, I think it's not a Golang style.
So my problem is: if the parent's Bar() method has some logic, for example, open a file, then read some lines, and use Foo() to output these lines to stdout, and the Child (in the example is B) wants to use most of them, the only difference is that the Child wants Foo() to output the lines to another file. How should I implement it? I have heard that Golang's inheritance can't work like C++ or Java, and what's right way in Golang?
package main
import (
"fmt"
)
type A struct {
}
func (a *A) Foo() {
fmt.Println("A.Foo()")
}
func (a *A) Bar() {
a.Foo()
}
type B struct {
A
}
func (b *B) Foo() {
fmt.Println("B.Foo()")
}
func main() {
b := B{A: A{}}
b.Bar()
}
output: A.Foo()
the following piece works, but when write
a := A{}
a.Bar()
you will encounter a compiler error
package main
import (
"fmt"
)
type I interface {
Foo()
}
type A struct {
i I
}
func (a *A) Foo() {
fmt.Println("A.Foo()")
}
func (a *A) Bar() {
a.i.Foo()
}
type B struct {
A
}
func (b *B) Foo() {
fmt.Println("B.Foo()")
}
func main() {
b := B{A: A{}}
b.i = &b // here i works like an attribute of b
b.Bar()
output: B.Foo()
As you wrote, what Go has is not really inheritance, the method that allows inheritance like features is called Embedding.
http://golang.org/doc/effective_go.html#embedding
What it means basically is that the embedded struct has no idea that it is embedded, so you cannot override anything that is called from it. You can actually take the embedded struct and take a reference for it only from the embedding struct.
So your best way to do it is more or less like your second example - through some sort of dependency injection using interfaces. i.e - A has a reference to some interface that does the actual work, say worker, that writes to a file or whatever. Then when instantiating B, you also replace A's worker with another worker (you can do it even without embedding A of course). The A just does something like myWorker.Work() without caring what worker it is.
Been struggling with this myself. Found 2 solutions:
Idiomatic Go way: implement the common "method" as external function with interface as argument.
package main
import "fmt"
// Fooer has to Foo
type Fooer interface {
Foo()
}
// Bar is a proxy, that calls Foo of specific instance.
func Bar(a Fooer) {
a.Foo()
}
//////////////////////////////////////////////////////////////////////
// usage
func main() {
b := &B{} // note it is a pointer
// also there's no need to specify values for default-initialized fields.
Bar(b) // prints: B.Foo()
}
//////////////////////////////////////////////////////////////////////
// implementation
// A is a "base class"
type A struct {
}
func (a *A) Foo() {
fmt.Println("A.Foo()")
}
// B overrides methods of A
type B struct {
A
}
func (b *B) Foo() {
fmt.Println("B.Foo()")
}
Try it on Go Playground: https://play.golang.org/p/2TbmHUs9_Dt
Similar to your second option: interface hackery. However, since Bar() is not specific to A (it is common to A and B), let's move it to base class, and hide implementation details and all dangerous stuff:
package main
import "fmt"
//////////////////////////////////////////////////////////////////////
// Usage
func main() {
b := NewB()
b.Bar() // prints: B.Foo()
a := NewA()
a.Bar() // prints: A.Foo()
}
//////////////////////////////////////////////////////////////////////
// Implementation.
// aBase is common "ancestor" for A and B.
type aBase struct {
ABCD // embed the interface. As it is just a pointer, it has to be initialized!
}
// Bar is common to A and B.
func (a *aBase) Bar() {
a.Foo() // aBase has no method Foo defined, so it calls Foo method of embedded interface.
}
// a class, not exported
type a struct {
aBase
}
func (a *a) Foo() {
fmt.Println("A.Foo()")
}
// b class, not exported
type b struct {
aBase
}
func (b *b) Foo() {
fmt.Println("B.Foo()")
}
//////////////////////////////////////////////////////////////////////
// Now, public functions and methods.
// ABCD describes all exported methods of A and B.
type ABCD interface {
Foo()
Bar()
}
// NewA returns new struct a
func NewA() ABCD {
a := &a{}
a.ABCD = a
return a
}
// NewB returns new struct b
func NewB() ABCD {
b := &b{}
b.ABCD = b
return b
}
Try it on Go Playground: https://play.golang.org/p/0Zcs_arturP
Recently I have a need to do this and the composition method proposed by OP works great.
I try to create another example to try to demonstrate the parent and child relationship and make it easier to read.
https://play.golang.org/p/9EmWhpyjHf:
package main
import (
"fmt"
"log"
)
type FruitType interface {
Wash() FruitType
Eat() string
}
type Fruit struct {
name string
dirty bool
fruit FruitType
}
func (f *Fruit) Wash() FruitType {
f.dirty = false
if f.fruit != nil {
return f.fruit
}
return f
}
func (f *Fruit) Eat() string {
if f.dirty {
return fmt.Sprintf("The %s is dirty, wash it first!", f.name)
}
return fmt.Sprintf("%s is so delicious!", f.name)
}
type Orange struct {
*Fruit
}
func NewOrange() *Orange {
ft := &Orange{&Fruit{"Orange", true, nil}}
ft.fruit = ft
return ft
}
func NewApple() *Fruit {
ft := &Fruit{"apple", true, nil}
return ft
}
func (o *Orange) Eat() string {
return "The orange is so sour!"
}
func main() {
log.Println(NewApple().Eat())
log.Println(NewApple().Wash().Eat())
log.Println(NewOrange().Eat())
log.Println(NewOrange().Wash().Eat())
}
Go does not support virtual method overriding. The design pattern you want to use is thus not directly supported by Go. It is considered bad practice because changing the implementation of A.Bar() would break all derived classes like B that assume A.Foo() will be called by A.Bar(). The design pattern you want to use will make your code brittle.
The way to do it in Go would be to define a Fooer interface with a Foo() method. A Fooer would be passed as argument to Bar() or stored in a field of A and called by A.Bar(). To change the Foo action, change the Fooer value. This is called composition, and it is much better than changing Foo action by inheritance and method overriding.
Here is an idiomatic way to do what you want to do in Go: https://play.golang.org/p/jJqXqmNUEHn. In this implementation, the Fooer is a member field of A that is initialized by a parameter of to the instance factory function NewA(). This design pattern is preferable when the Fooer doesn't change frequently during the lifetime of A. Otherwise, you may pass the Fooer as parameter of the Bar() method.
This is how we change the behavior of Foo() in Go. It is called composition because you change the behavior of Bar() by changing the instances composing A.
package main
import (
"fmt"
)
type Fooer interface {
Foo()
}
type A struct {
f Fooer
}
func (a *A) Bar() {
a.f.Foo()
}
func NewA(f Fooer) *A {
return &A{f: f}
}
type B struct {
}
func (b *B) Foo() {
fmt.Println("B.Foo()")
}
type C struct {
}
func (c *C) Foo() {
fmt.Println("C.Foo()")
}
func main() {
a := NewA(new(B))
a.Bar()
a.f = &C{}
a.Bar()
}
PS: Here is a possible implementation of the design pattern you wanted to implement for documentation purpose: https://play.golang.org/p/HugjIbYbout
package main
import (
"fmt"
)
//-- polymorphism in work
// children specification by methods signatures
// you should define overridable methods here
type AChildInterface interface {
Foo()
}
type A struct {
child AChildInterface
}
//-- /polymorphism in work
// hard A.Bar method
func (a *A) Bar() {
a.child.Foo() // Foo() will be overwritten = implemented in a specified child
}
//-- default implementations of changeable methods
type ADefaults struct{}
func (ad ADefaults) Foo() {
fmt.Println("A.Foo()")
}
//-- /default
//-- specified child
type B struct {
ADefaults // implement default A methods from ADefaults, not necessary in this example
}
// overwrite specified method
func (b B) Foo() {
fmt.Println("B.Foo()")
}
//-- /specified child
func main() {
a := A{ADefaults{}}
a.Bar()
// Golang-style inheritance = embedding child
b := A{B{}} // note: we created __Parent__ with specified __Child__ to change behavior
b.Bar()
}
Output:
A.Foo()
B.Foo()
Coming from C++/Python, where OOP is much better represented, and discovering go (now everything is web or web related, right?!) I too stumbled upon this issue. I feel that OOP in go is only half-baked. With embedding (struct's anonymous fields), methods of the inner type come along for free, inducing the idea of inheritance, only to learn later on the limitations. However, playing a bit with embedded interfaces within structs and with a bit of discipline, C++-like constructors, inheritance, polymorphism, and methods override can be emulated.
Considering the example - https://play.golang.org/p/nqt0haPYt2x
package main
import (
"bytes"
"fmt"
"log"
"math"
"unsafe"
)
//Emulate C++ like polymorphism in go, through template method design pattern
//========================== Shape interface ==============================
//like C++ abstract classes
type Shape interface {
Area() float32 //Shape's area
Perimeter() float32 //Shape's perimeter
Name() string //Shape's name (like rectangle, circle, square etc.)
}
//====================== PrintableShapeInfo =============================
type PrintableShapeInfo struct {
Shape //like C++ inheritance, although go has no such a thing
preetyPrintPrefix string
}
//Init a new PrintableShapeInfo object. The method is distinct so that it can be called from other contexts as well
//
//Remark: emulates the C++ constructor init part
func (printableShapeInfo *PrintableShapeInfo) Init(preetyPrintPrefix string) {
printableShapeInfo.preetyPrintPrefix = preetyPrintPrefix
}
//The central method emulates the template method design pattern. It prints some info about a shape by dynamically calling (through pointers) the right methods
//
//Remark: the design patterns best practices recommend to favor composition over inheritance (i.e. model a ShapeInfoPrinter class, which takes a Shape interface and prints its info),
//for the sake of showcasting the template method pattern, the "go's inheritange" like model was chosen
func (printableShapeInfo *PrintableShapeInfo) PrintInfo() {
log.Println("PrintableShapeInfo::PrintInfo")
fmt.Printf("%s PrintableShapeInfo::PrintInfo - %s:\n",
printableShapeInfo.preetyPrintPrefix, printableShapeInfo.Name()) //dynamically calls (through a pointer) a shape's Name method (like Rectangle.Name or Circle.Name or Square.Name)
fmt.Printf("\tArea: %f\n", printableShapeInfo.Area()) //dynamically calls (through a pointer) a shape's Area method (like Rectangle.Area or Circle.Area or Square.Area)
fmt.Printf("\tPerimeter: %f\n", printableShapeInfo.Perimeter()) //dynamically calls (through a pointer) a shape's Perimeter method (like Rectangle.Perimeter or Circle.Perimeter or Square.Perimeter)
}
//====================== Rectangle =============================
type Rectangle struct {
PrintableShapeInfo //like C++ inheritence, although go has no such a thing
width float32 //rectangle's width
height float32 //rectangle's heigh
}
//Creates and init a new rectangle object and properly set its Shape's interface methods set (similar to C++ class' vtable)
//
//Remark: emulates the C++ constructor
func NewRectangle(width float32, height float32) *Rectangle {
log.Println("NewRectangle")
rectangle := new(Rectangle) //allocate data
rectangle.Shape = rectangle //set the Shape's specific vtable with the Rectangle's methods. Critical for template method pattern
rectangle.Init(width, height) //init class
return rectangle
}
//Init a new rectangle object. The method is distinct so that it can be called from other contexts as well (such as a square Init method. See below)
//
//Remark: emulates the C++ constructor init part
func (rectangle *Rectangle) Init(width float32, height float32) {
log.Println("Rectangle::Init")
//call the base's PrintableShapeInfo struct Init method
rectangle.PrintableShapeInfo.Init("###")
rectangle.width = width
rectangle.height = height
}
//Compute the rectangle's area
func (rectangle *Rectangle) Area() float32 {
log.Println("Rectangle::Area")
return float32(rectangle.width * rectangle.height)
}
//Compute the rectangle's perimeter
func (rectangle *Rectangle) Perimeter() float32 {
log.Println("Rectangle::Perimeter")
return float32(2 * (rectangle.width + rectangle.height))
}
//Get the rectangle's object name
func (rectangle *Rectangle) Name() string {
log.Println("Rectangle::Name")
return "rectangle"
}
//====================== Circle =============================
type Circle struct {
PrintableShapeInfo //like C++ inheritence, although go has no such a thing
radius float32 //circle's radius
}
//Creates and init a new circle object and properly set its Shape's interface methods set (similar to C++ class' vtable)
//
//Remark: emulates the C++ constructor
func NewCircle(radius float32) *Circle {
log.Println("NewCircle")
circle := new(Circle) //allocate data
circle.Shape = circle //set the Shape's specific vtable with the Rectangle's methods. Critical for template method pattern
circle.Init(radius) //init class
return circle
}
//Init a new circle object. The method is distinct so that it can be called from other contexts as well if needed
//
//Remark: emulates the C++ constructor init part
func (circle *Circle) Init(radius float32) {
log.Println("Circle::Init")
//call the base's PrintableShapeInfo struct Init method
circle.PrintableShapeInfo.Init("ooo")
circle.radius = radius
}
//Compute the circle's area
func (circle *Circle) Area() float32 {
log.Println("Circle::Area")
return math.Pi * float32(circle.radius*circle.radius)
}
//Compute the circle's perimeter
func (circle *Circle) Perimeter() float32 {
log.Println("Circle::Perimeter")
return 2 * math.Pi * float32(circle.radius)
}
//Get the circle's object name
func (circle *Circle) Name() string {
log.Println("Circle::Name")
return "circle"
}
//====================== Rectangle =============================
//Implement Square in terms of Rectangle
type Square struct {
Rectangle //like C++ inheritance, although go has no such a thing
}
//Creates and init a new square object and properly set its Shape's interface methods set (similar to C++ class' vtable)
//
//Remark: emulates the C++ constructor init
func NewSquare(width float32) *Square {
log.Println("NewSquare")
square := new(Square) //allocate data
square.Shape = square //set the Shape's specific vtable with the Rectangle's methods. Critical for template method pattern
square.Init(width) //init class
return square
}
//Init a new square object. The method is distinct so that it can be called from other contexts as well if needed
//
//Remark: emulates the C++ constructor init part
func (square *Square) Init(width float32) {
log.Println("Square::Init")
//since the Rectangle field is anonymous it's nice that we can directly call its un-overwritten methods but we can still access it, as named Rectangle, along with its (even overwritten) methods
square.Rectangle.Init(width, width) //call Rectangle's init to initialize its members. Since Square is implemented in Rectangle's terms, there nothing else needed
}
//Compute the square's area
func (square *Square) Area() float32 {
log.Println("Square::Area")
//since the Rectangle field is anonymous it's nice that we can directly call it's un-overwritten methods but we can still access it, as named Rectangle, along with it's (even overwritten) methods
return square.Rectangle.Area()
}
//Compute the square's perimeter
func (square *Square) Perimeter() float32 {
log.Println("Square::Perimeter")
//since the Rectangle field is anonymous it's nice that we can directly call it's un-overwritten methods but we can still access it, as named Rectangle, along with it's (even overwritten) methods
return square.Rectangle.Perimeter()
}
//Get the square's object name
func (square *Square) Name() string {
log.Println("Square::Name")
return "square"
}
func main() {
//initialize log subsystem so that we can display them at the main's end
// bufWriter := bytes.NewBuffer()
logStringWriter := bytes.NewBufferString("")
log.SetOutput(logStringWriter)
rectangle := NewRectangle(2, 3) //create a Rectangle object
rectangle.PrintInfo() //should manifest polymorphism behavior by calling Rectangle's Area, Perimeter and Name methods
circle := NewCircle(2) //create a Circle object
circle.PrintInfo() //should manifest polymorphism behavior by calling Circle's Area, Perimeter and Name methods
square := NewSquare(3) //create a Square object
square.PrintInfo() //should manifest polymorphism behavior by calling Square's Area, Perimeter and Name methods
//print constructs sizes
fmt.Printf(`
Go constructs sizes:
Shape interface size as seen by Rectangle struct: %d
`, unsafe.Sizeof(rectangle.Shape))
fmt.Printf("\tRectangle struct size: %d", unsafe.Sizeof(rectangle))
fmt.Printf(`
Shape interface size as seen by Circle struct: %d
`, unsafe.Sizeof(circle.Shape))
fmt.Printf("\tCircle struct size: %d", unsafe.Sizeof(circle))
fmt.Printf(`
Shape interface size as seen by Square struct: %d
`, unsafe.Sizeof(square.Shape))
fmt.Printf("\tCircle struct size: %d", unsafe.Sizeof(square))
//print the logs
fmt.Println("\n\nDumping traces")
fmt.Print(logStringWriter)
return
}
The central method (template method) is PrintInfo which, called for any defined shape, works as expected, by calling the right Area, Perimeter, and Name methods. Ex. circle.PrintInfo() will call circle.Area, circle.Perimeter and circle.Name.
The constructor functions, NewRectangle, NewCircle, and NewSquare construct shape objects and they're split into three steps:
space allocation
methods set (C++ like vtable) init, needed for polymorphic behavior
struct members initialization, through Init methods
The struct member initialization is a distinct step for better code reuse. For example, Rectangle Init calls the base PrintableShapeInfo Init method while the Square Init method calls the base Rectangle Init (which calls PrintableShapeInfo Init, as said before).
Also, due to interfaces embedding, the object sizes increases only a bit, with a pair of pointers to the methods set and data area as can be seen in the example output.
I think the code looks pretty decent and the only concern being if specifically setting the Shape's interface method set (as the case of NewRectangle, NewCircle, and NewSquare functions) would trigger some side effects, as the code appears to work correctly?!