Last active
January 24, 2017 23:11
-
-
Save rande/4522a0f38a972cc5532855a65750d0e3 to your computer and use it in GitHub Desktop.
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" | |
"encoding/json" | |
"io/ioutil" | |
) | |
type User struct { | |
Name string `json:"name"` | |
} | |
// define function signatures as interface ... | |
type Loader func(string) (interface{}, error) | |
type Validator func(interface{}) bool | |
// Create a Loader instance with parameter in the constructor (ie, CreateLoader) | |
func CreateLoader(baseDir string) Loader { | |
// inner function, ie private function | |
unmarshalUser := func(data []byte) (*User, error) { | |
u := &User{} | |
if err := json.Unmarshal(data, u); err != nil { | |
return nil, err | |
} | |
return u, nil | |
} | |
// return the loader, variables and methods in the current scope | |
// are just private. | |
return func(name string) (interface{}, error) { | |
if data, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", baseDir, name)); err != nil { | |
return nil, err | |
} else { | |
return unmarshalUser(data) | |
} | |
} | |
} | |
// Create a Validator instance with parameter in the constructor (ie, CreateValidator) | |
func CreateValidator() Validator { | |
validateUser := func(user *User) bool { | |
return len(user.Name) > 0 | |
} | |
return func(v interface{}) bool { | |
switch t := v.(type) { | |
case *User: | |
return validateUser(t) | |
default: | |
return false | |
} | |
} | |
} | |
// of course, we can pass dependencies ... no need to know the method name ... | |
func execute(loader Loader, validator Validator) { | |
// some codes | |
if data, err := loader("data.json"); err != nil { | |
fmt.Print("Error while loading: ", err) | |
} else { | |
if validator(data) { | |
fmt.Printf("Data is valid") | |
} else { | |
fmt.Printf("Data is not valid") | |
} | |
} | |
} | |
func main() { | |
// create closures with one responsibility ... | |
loader := CreateLoader("./fixtures"); | |
validator := CreateValidator(); | |
execute(loader, validator) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment