Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
xujihui1985 committed Sep 24, 2018
1 parent 4b1a6ba commit 045fd03
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 4 deletions.
8 changes: 4 additions & 4 deletions design/decouple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ func (*Solar) Store(d *Data) error {

// We should embed for behaiver
type System struct {
Xenia
Solar
Puller
Storer
}

func pull(p Puller, data []Data) (int, error) {
Expand Down Expand Up @@ -76,8 +76,8 @@ func Copy(ps PullStorer, batch int) error {

func main() {
sys := System{
Xenia: Xenia{},
Solar: Solar{},
Puller: &Xenia{},
Storer: &Solar{},
}

if err := Copy(&sys, 3); err != io.EOF {
Expand Down
94 changes: 94 additions & 0 deletions design/interface/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"fmt"
"math/rand"
"time"
)

type Mover interface {
Move()
}

type Locker interface {
Lock()
Unlock()
}

type MoveLocker interface {
Mover
Locker
}

type bike struct {
}

func (bike) Move() {
fmt.Println("moving the bike")
}

func (bike) Lock() {
fmt.Println("locking the bike")
}

func (bike) Unlock() {
fmt.Println("unlocking the bike")
}

func assignMoveLockerToMover() {
var ml MoveLocker
var m Mover

ml = bike{}
m = ml

m.Move()
}

func assignMoverToMoverLocker() {
// var m Mover
// var ml MoveLocker

// m = bike{}
// Mover does not implement movelocker (missing lock method)
// ml = m

// m.Move()
}

func typeAssertion() {
var m Mover
var ml MoveLocker
m = bike{}

// if we are pretty sure the Mover interface type stored are bike,
// we can perform a type assertion against the mover interface value to access
// a COPY of the concrete type value of type bike that was stored inside of it.
// then assign the COPY of the concrete type to the MoveLocker interface
b, ok := m.(bike)
if !ok {
return
}
ml = b
ml.Move()
ml.Lock()
}

type cloud struct{}

func (cloud) String() string {
return "Big Data"
}

func main() {
rand.Seed(time.Now().UnixNano())
// mvs := []fmt.Stringer{
// cloud{},
// }

for i := 0; i < 10; i++ {
rn := rand.Int()
fmt.Println(rn)
}

}
50 changes: 50 additions & 0 deletions design/pollution/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

type Server interface {
Start() error
Stop() error
Wait() error
}

//
type server struct {
}

func (*server) Start() error {
return nil
}
func (*server) Stop() error {
return nil
}
func (*server) Wait() error {
return nil
}

func NewServer() Server {
return &server{}
}

func main() {
s := NewServer()
s.Start()
s.Wait()
s.Stop()
}

// Smells:
// The package declares an interface that matches the entire API of its own concrete type
// The interface is exported but the concrete type is unexported
// the factor function returns the interface value with the unexported concreate type value
// the interface can be removed and nothing changes for the user of the API
// the interface is not decoupling the API from change

// NOTES:
// * Use an interface:
// When users of the API need to provide an implementation detail
// When API's have multiple implementations that need to be maintained
// When parts of the API that can change have been identified and required decoupling

// Question an interface:
// when its only purpose is for writing testable api
// when it's not providing support for the api to decouple from change
// when it's not clear how the interface makes the code better
5 changes: 5 additions & 0 deletions errorhandling/behavior_as_context/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {

}
38 changes: 38 additions & 0 deletions errorhandling/bug/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// always return error interface
package main

import "fmt"

type CustomError struct {
}

func (*CustomError) Error() string {
return ""
}

func dosth() error {
return nil
}

func dosth2() error {
var e *CustomError
return e
}

func main() {
var err error = nil
var err2 *CustomError = nil
var err3 *CustomError = err2
err4 := dosth()
err5 := err2
var err6 error = err2
err7 := dosth2()

fmt.Println("err == nil", err == nil)
fmt.Println("err2 == nil", err2 == nil)
fmt.Println("err3 == nil", err3 == nil)
fmt.Println("err4 == nil", err4 == nil)
fmt.Println("err5 == nil", err5 == nil)
fmt.Println("err6 == nil", err6 == nil)
fmt.Println("err7 == nil", err7 == nil)
}
35 changes: 35 additions & 0 deletions errorhandling/error_variables/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"errors"
"fmt"
)

var (
// the error variable convension is Errxxxx
ErrBadRequest = errors.New("Bad requests")
ErrMovedPermanently = errors.New("moved permanently")
)

func main() {
if err := call(true); err != nil {
switch err {
case ErrBadRequest:
fmt.Println("bad request")
return
case ErrMovedPermanently:
fmt.Println("moved permanently")
return
default:
fmt.Println("unknown")
}
}

}

func call(v bool) error {
if v {
return ErrBadRequest
}
return ErrMovedPermanently
}

0 comments on commit 045fd03

Please sign in to comment.