Last active
October 13, 2023 16:25
-
-
Save reidcooper/0337591d8a5ce9af23f00d64ed395e83 to your computer and use it in GitHub Desktop.
functional_composition.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
) | |
type DatabaseFetcher struct { | |
databaseRepo string | |
} | |
func (idr *DatabaseFetcher) GetListOfIds(ids []string) []string { | |
return []string{"1", "2", "3"} | |
} | |
// ==== | |
type RedisFetcher struct { | |
databaseRepo string | |
} | |
func (idr *RedisFetcher) GetListOfIds(ids []string) []string { | |
return []string{"1", "2", "3"} | |
} | |
// ==== | |
type IdFetcher interface { | |
GetListOfIds(ids []string) []string | |
} | |
type CalculateCountOfIds struct { | |
idFetcher IdFetcher | |
} | |
func (cci *CalculateCountOfIds) CountIds(ids []string) int { | |
return len(cci.idFetcher.GetListOfIds(ids)) | |
} | |
// ==== | |
type Calculator interface { | |
CountIds(ids []string) int | |
} | |
type SomeController struct { | |
calculator Calculator | |
} | |
func (controller *SomeController) MakeItAString() string { | |
count := controller.calculator.CountIds([]string{"1", "2", "3"}) | |
return fmt.Sprint(count) | |
} | |
func BuildSomeController() SomeController { | |
idDBFetcher := DatabaseFetcher{} | |
calculator := &CalculateCountOfIds{ | |
idFetcher: &idDBFetcher, | |
} | |
controller := SomeController{ | |
calculator: calculator, | |
} | |
return controller | |
} | |
// ==== | |
type mockCalculator struct { | |
countIds func(ids []string) int | |
} | |
func (mc *mockCalculator) CountIds(ids []string) int { | |
return mc.countIds(ids) | |
} | |
func TestSomeControllerMakeItAString(t *testing.T) { | |
mc := mockCalculator{} | |
mc.countIds = func(ids []string) int { | |
return 4 | |
} | |
controller := SomeController{ | |
calculator: &mc, | |
} | |
assert.Equal(t, "4", controller.MakeItAString()) | |
} | |
// ==== | |
// Now for the Functional Side (Below) | |
// ==== | |
type CountIdsFunc func(ids []string) int | |
func NewCountIdsFromDatabaseFunc(databaseFetcher *DatabaseFetcher) CountIdsFunc { | |
return func(ids []string) int { | |
return CountIdsFromDatabase(ids, databaseFetcher) | |
} | |
} | |
func CountIdsFromDatabase(ids []string, databaseFetcher *DatabaseFetcher) int { | |
return len(databaseFetcher.GetListOfIds(ids)) | |
} | |
func NewCountIdsFromRedisFunc(redisFetcher *RedisFetcher) CountIdsFunc { | |
return func(ids []string) int { | |
return CountIdsFromRedis(ids, redisFetcher) | |
} | |
} | |
func CountIdsFromRedis(ids []string, redisFetcher *RedisFetcher) int { | |
return len(redisFetcher.GetListOfIds(ids)) | |
} | |
// ==== | |
type SomeFuncController struct { | |
calculator CountIdsFunc | |
} | |
func (controller *SomeFuncController) MakeItAString() string { | |
result := controller.calculator([]string{"1", "2", "3"}) | |
return fmt.Sprint(result) | |
} | |
func BuildSomeFuncController() SomeFuncController { | |
idRedisFetcher := RedisFetcher{} | |
countFunc := NewCountIdsFromRedisFunc(&idRedisFetcher) | |
controller := SomeFuncController{ | |
calculator: countFunc, | |
} | |
return controller | |
} | |
// ==== | |
func TestSomeFuncControllerMakeItAString(t *testing.T) { | |
calcFunc := func(ids []string) int { | |
return 4 | |
} | |
controller := SomeFuncController{ | |
calculator: calcFunc, | |
} | |
assert.Equal(t, "4", controller.MakeItAString()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment