main.go:(使用者)
package mainimport "fmt"type Retriever interface {Get(url string) string}type Poster interface {Post(url string, form map[string]string) string}const url = "http://www.imooc.com"func download(r Retriever) string {return r.Get(url)}func post(poster Poster) {poster.Post(url,map[string]string {"name": "ccmouse","course": "golang",})}// 接口的组合:组合Retriever接口和Poster接口type RetrieverPoster interface {RetrieverPoster}func session(s RetrieverPoster) string {s.Post(url, map[string]string {"contents": "another faked imooc.com",})return s.Get(url)}func main() {var r Retrieverretriever := mock.Retriever{"this is a fake imooc.com"}r = &retrieverinspect(r)r = &real.Retriever{UserAgent: "Mozilla/5.0",TimeOut: time.Minute,}inspect(r)// Type assertionif mockRetriever, ok := r.(*mock.Retrivever); ok {fmt.Println(mockRetriever.Contents)} else {fmt.Println("not a mock retriever")}fmt.Println("Try a session")fmt.Println(session(&retriever)) // another faked imooc.com}func inspect(r Retriever) {switch v := r.(type) {case *mock.Retriever:fmt.Println("Contents:", v.Contents)case *real.Retriever:fmt.Println("UserAgent:", v.UserAgent)}}
mockretriever.go:(实现者)
package mock
type Retriever struct {
Contents string
}
// 只要实现了Post方法和Get方法,就实现了RetrieverPoster接口
func (r *Retriever) Post(url string, form map[string]string) string {
r.Contents = form["contents"]
return "ok"
}
func (r *Retriever) Get(url string) string {
return r.Contents
}
retriever.go:(实现者)
package real
import (
"net/http"
"net/http/httputil"
"time"
)
type Retriever struct {
UserAgent string
TimeOut time.Duration
}
// 指针接收者
func (r *Retriever) Get(url string) string {
resp, err := http.Get(url)
if err != nil {
panic(err)
}
result, err := httputil.DumpResponse(
resp, true)
resp.Body.Close()
if err != nil {
panic(err)
}
return string(result)
}
