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)
Related
I am trying to write a unit test code form following code which has 3 level of function calling as below:
The main function calls function A() and then function A calls function B() and C() depending upon some condition and function B calls function E() and F(), whereas function C calls function G() and H() on some condition.
The above like the code I have developed, Here I want to mock function E() and F() for function B, and G() and H() for function C. Please suggest me how to do it using interface.
Abstract function type
You can do it with dependency injection not using interfaces:
import (
"fmt"
"math"
)
type a func(float64) float64
func A(arg float64) float64 {
return math.Pow(arg, 2)
}
func mock(arg float64) float64 {
return math.Sqrt(arg)
}
func b(function a, arg float64) float64 {
return function(arg)
}
func main() {
fmt.Println(b(A, 2))
fmt.Println(b(mock, 2))
}
Function is first class citizen in Go
In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities.
It means you can pass function as argument among other possibilities. And of course you can declare an abstract type based on function with concrete interface (Don't confuse with interface type)
Interface approach
You can make compositions using your functions
import (
"fmt"
"math"
)
// Declare an interface type with dependencies
type HGer interface {
H(float64) float64
G(float64) float64
}
// Declare a dependent type with embedded interface
type Dependent struct {
HGer
}
func (d *Dependent) B(arg float64) float64 {
return d.H(arg) * d.G(arg)
}
// Implement the interface for an actual program
type ImplHGer struct{}
func (i *ImplHGer) H(arg float64) float64 {
return math.Pow(arg, 2)
}
func (i *ImplHGer) G(arg float64) float64 {
return math.Sqrt(arg)
}
// Implement the interface for mock of dependencies
type MockHGer struct{}
func (i *MockHGer) H(arg float64) float64 {
return float64(0)
}
func (i *MockHGer) G(arg float64) float64 {
return float64(0)
}
func main() {
// Use real implementation
a := Dependent{new(ImplHGer)}
// Use the mock
b := Dependent{new(MockHGer)}
fmt.Println(a.B(8)) // 181.01933598375618
fmt.Println(b.B(8)) // 0
}
Embedding
Including an anonymous field in a struct is known as embedding. In this case the Discount type is embedded in the PremiumDiscount type. All the methods of Discount are instantly available on the PremiumDiscount type. Furthermore those same methods can be hidden
It is possible to embed interface to struct to extend it's behavior or to be more specific - declare abstract dependency.
I would like to better understand how to use interfaces, mainly to split code in reusable components and at the same time make it more easy for testing, currently my main question is how to share/get data between the interfaces that belong to a main interface, for example:
https://play.golang.org/p/67CQor1_pY
package main
import (
"fmt"
)
type MainInterface interface {
SubInterfaceA
SubInterfaceB
}
type SubInterfaceA interface {
MethodA()
GetterA(s implementMain)
}
type SubInterfaceB interface {
MethodB()
GetterB(s implementMain)
}
type implementA struct{}
func (ia *implementA) MethodA() { fmt.Println("I am method A") }
func (ia *implementA) GetterA(s implementMain) {
fmt.Println(s.Data)
}
type implementB struct{}
func (ib *implementB) MethodB() { fmt.Println("I am method B") }
func (ib *implementB) GetterB(s implementMain) {
fmt.Println(s.Data)
}
type implementMain struct {
Data string
SubInterfaceA
SubInterfaceB
}
func New(d string) implementMain {
return implementMain{
Data: d,
SubInterfaceA: &implementA{},
SubInterfaceB: &implementB{},
}
}
func main() {
var m MainInterface
m = New("something")
fmt.Println(m.(implementMain).Data)
m.MethodA() // prints I am method A
m.MethodB() // prints I am method B
m.GetterA(m.(implementMain)) // prints "something"
m.GetterB(m.(implementMain)) // prints "something"
}
In the above code, within the methods of struct implementA or implementB how to access the struct elements of the parent holder implementMain that implements MainInterface without passing it as an argument?
with holder struct I mean:
type implementMain struct {
Data string
SubInterfaceA
SubInterfaceB
}
If I am right SubInterfaceA and SubInterfaceB are embedded and help to make the struct implementMain satisfy the MainInterface:
type MainInterface interface {
SubInterfaceA
SubInterfaceB
}
But within the embedded methods of the SubInterfaceA or subInterfaceB what is the best practice to use in order to be available to get the data string?
I created Getter(s implementMain) method and passed the holder struct, but had to cast type:
m.GetterA(m.(implementMain))
I don't know if by satisfying a interface, all the involved interfaces can become part of the same structure scope and if they do, how to get/share data between them or either between its components?, for example besides been available to reach data string how from SubInterfaceA get/access SubInterfaceB
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? 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/
Is there a way to specify the return type of a function to be the type of the called object?
e.g.
trait Foo {
fun bar(): <??> /* what to put here? */ {
return this
}
}
class FooClassA : Foo {
fun a() {}
}
class FooClassB : Foo {
fun b() {}
}
// this is the desired effect:
val a = FooClassA().bar() // should be of type FooClassA
a.a() // so this would work
val b = FooClassB().bar() // should be of type FooClassB
b.b() // so this would work
In effect, this would be roughly equivalent to instancetype in Objective-C or Self in Swift.
There's no language feature supporting this, but you can always use recursive generics (which is the pattern many libraries use):
// Define a recursive generic parameter Me
trait Foo<Me: Foo<Me>> {
fun bar(): Me {
// Here we have to cast, because the compiler does not know that Me is the same as this class
return this as Me
}
}
// In subclasses, pass itself to the superclass as an argument:
class FooClassA : Foo<FooClassA> {
fun a() {}
}
class FooClassB : Foo<FooClassB> {
fun b() {}
}
You can return something's own type with extension functions.
interface ExampleInterface
// Everything that implements ExampleInterface will have this method.
fun <T : ExampleInterface> T.doSomething(): T {
return this
}
class ClassA : ExampleInterface {
fun classASpecificMethod() {}
}
class ClassB : ExampleInterface {
fun classBSpecificMethod() {}
}
fun example() {
// doSomething() returns ClassA!
ClassA().doSomething().classASpecificMethod()
// doSomething() returns ClassB!
ClassB().doSomething().classBSpecificMethod()
}
You can use an extension method to achieve the "returns same type" effect. Here's a quick example that shows a base type with multiple type parameters and an extension method that takes a function which operates on an instance of said type:
public abstract class BuilderBase<A, B> {}
public fun <B : BuilderBase<*, *>> B.doIt(): B {
// Do something
return this
}
public class MyBuilder : BuilderBase<Int,String>() {}
public fun demo() {
val b : MyBuilder = MyBuilder().doIt()
}
Since extension methods are resolved statically (at least as of M12), you may need to have the extension delegate the actual implementation to its this should you need type-specific behaviors.
Recursive Type Bound
The pattern you have shown in the question is known as recursive type bound in the JVM world. A recursive type is one that includes a function that uses that type itself as a type for its parameter or its return value. In your example, you are using the same type for the return value by saying return this.
Example
Let's understand this with a simple and real example. We'll replace trait from your example with interface because trait is now deprecated in Kotlin. In this example, the interface VitaminSource returns different implementations of the sources of different vitamins.
In the following interface, you can see that its type parameter has itself as an upper bound. This is why it's known as recursive type bound:
VitaminSource.kt
interface VitaminSource<T: VitaminSource<T>> {
fun getSource(): T {
#Suppress("UNCHECKED_CAST")
return this as T
}
}
We suppress the UNCHECKED_CAST warning because the compiler can't possibly know whether we passed the same class name as a type argument.
Then we extend the interface with concrete implementations:
Carrot.kt
class Carrot : VitaminSource<Carrot> {
fun getVitaminA() = println("Vitamin A")
}
Banana.kt
class Banana : VitaminSource<Banana> {
fun getVitaminB() = println("Vitamin B")
}
While extending the classes, you must make sure to pass the same class to the interface otherwise you'll get ClassCastException at runtime:
class Banana : VitaminSource<Banana> // OK
class Banana : VitaminSource<Carrot> // No compiler error but exception at runtime
Test.kt
fun main() {
val carrot = Carrot().getSource()
carrot.getVitaminA()
val banana = Banana().getSource()
banana.getVitaminB()
}
That's it! Hope that helps.
Depending on the exact use case, scope functions can be a good alternative. For the builder pattern apply seems to be most useful because the context object is this and the result of the scope function is this as well.
Consider this example for a builder of List with a specialized builder subclass:
open class ListBuilder<E> {
// Return type does not matter, could also use Unit and not return anything
// But might be good to avoid that to not force users to use scope functions
fun add(element: E): ListBuilder<E> {
...
return this
}
fun buildList(): List<E> {
...
}
}
class EnhancedListBuilder<E>: ListBuilder<E>() {
fun addTwice(element: E): EnhancedListBuilder<E> {
addNTimes(element, 2)
return this
}
fun addNTimes(element: E, times: Int): EnhancedListBuilder<E> {
repeat(times) {
add(element)
}
return this
}
}
// Usage of builder:
val list = EnhancedListBuilder<String>().apply {
add("a") // Note: This would return only ListBuilder
addTwice("b")
addNTimes("c", 3)
}.buildList()
However, this only works if all methods have this as result. If one of the methods actually creates a new instance, then that instance would be discarded.
This is based on this answer to a similar question.
You can do it also via extension functions.
class Foo
fun <T: Foo>T.someFun(): T {
return this
}
Foo().someFun().someFun()