http.HandleFunc関数におけるAdapterとしての実装の理解

# 概要
- [Go Design Patterns](https://www.amazon.co.jp/Design-Patterns-Mario-Castro-Contreras-ebook/dp/B01IHOVFIQ "Go Design Patterns") の中で、Go の標準ライブラリで Adapter Pattren が使用されている例として
 http.HandleFunc関数について触れられていた。そこで理解したことをここに書く。(io.Pipe関数についても触れられているが、これについては次回書く。）
- Adapter Pattern は、本来は異なるインタフェースを目的のインタフェースとして使用できるように変換する方法。Adapter が変換のための部品。
- http.HandleFunc関数は、任意の関数を http.Handlerインターフェースが持つ ServeHTTP メソッドの実装として変換する Adapter。
- ↑と思ったが、本当はhttp.HandlerFunc型が Adapterとしての核？

# Adapter としての http.HandleFunc
- httpサーバのルートパスと関数の登録において、http.Handlerインタフェースを実装する書き方とhttp.HandleFunc関数に自分で実装した関数を渡す書き方がある。
- http.HandleFunc関数が Adapterに相当する。

## http.Handlerインタフェースを実装する書き方
- http.Handleメソッドにルートパスと http.Handlerインタフェースを渡す。
- http.Handlerインタフェースを満たす型を実装し、ServeHTTPメソッドに目的の処理を実装する。
- 下記のソースコードは、Go Designe Patterns より引用。

```golang
type MyServer struct {
	Msg string
}

func (m *MyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, m.Msg)
}

func main() {
	server := &MyServer{
		Msg: "Hello, World",
	}

	http.Handle("/", server)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
```
## http.HandleFunc関数を使用する書き方
- http.HandleFunc関数にルートパスと、http.ResponseWriter と *http.Request を引数とする関数を渡す。この関数の中に目的の処理を実装する。
-  下記のソースコードは、Go Designe Patterns より引用。

```golang
func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World")
	})

	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

## http.HandleFunc関数の中身を追う
- https://golang.org/src/net/http/server.go を読む。
- http.Handle関数も、http.HandleFunc関数も最終的には以下の(mux *ServeMux)Handle関数を呼び出して、http.Handlerインタフェースを登録する。

```golang
// Handle registers the handler for the given pattern.
  2341  // If a handler already exists for pattern, Handle panics.
  2342  func (mux *ServeMux) Handle(pattern string, handler Handler) {
```
- http.Handle関数の場合、内部で(mux *ServeMux)Handle関数を直接呼んでいる。

```golang
// Handle registers the handler for the given pattern
  2372  // in the DefaultServeMux.
  2373  // The documentation for ServeMux explains how patterns are matched.
  2374  func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
```
- http.HandleFunc関数の場合、(mux *ServeMux)HandleFunc関数を呼び出し、その関数の中で、(mux *ServeMux)Handleが呼び出されている。その際に、func(ResponseWriter, *Request)を満たす関数として渡されたhandlerは、HandlerFunc型にキャストして渡されている。

```golang
// HandleFunc registers the handler function for the given pattern
  2377  // in the DefaultServeMux.
  2378  // The documentation for ServeMux explains how patterns are matched.
  2379  func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  2380  	DefaultServeMux.HandleFunc(pattern, handler)
  2381  }
```
```golang
// HandleFunc registers the handler function for the given pattern.
  2367  func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  2368  	mux.Handle(pattern, HandlerFunc(handler))
  2369  }
```
- HandlerFunc型は、ServeHTTPメソッドを持つため、http.Handlerインタフェースとして使用することができる。http.HandleFunc関数に渡されたfunc(ResponseWriter, *Request)の型の関数は、最終的にhttp.HandlerFunc型にキャストすることで、http.Hanlderインターフェースに変換されている。

```golang
// The HandlerFunc type is an adapter to allow the use of
  1940  // ordinary functions as HTTP handlers. If f is a function
  1941  // with the appropriate signature, HandlerFunc(f) is a
  1942  // Handler that calls f.
  1943  type HandlerFunc func(ResponseWriter, *Request)
  1944  
  1945  // ServeHTTP calls f(w, r).
  1946  func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  1947  	f(w, r)
  1948  }
```

## http.HandlerFunc型にキャストすれば、http.Handle関数も使えるのでは
- 使えた。
- http.HandleFunc関数の意義は、キャストを省略すること・・・？

```golang
func main() {
	http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World")
	}))

	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

# まとめ
- Go Design Patterns の中では、以下のように書かれており、http.HandleFunc関数が Adapter としているが、実際の Adapter としての役割は、http.HandlerFunc型が果たしている気がした。

> The HandleFunc function is actually part of an adapter for using functions directly as ServeHTTP implementations.

- GOの標準ライブラリのソースコードを読んだことがあまりなかったので、良いトレーニングになった。
- 今回初めて記事を書いたが、本を読むだけで理解した気になっていたことが、記事を書くうちに勘違いして理解していた部分などに気づけた(http.HandleFunc関数とhttp.HandlerFunc型を区別できていなかった）。実際のソースコードの中身を見たり、他の方の記事を読むことで理解が深まった。

# 参考にさせていただいた記事
- [net/http の動きを少しだけ追ってみた - Golang](https://m0t0k1ch1st0ry.com/blog/2014/06/09/golang/ "")
 - net/http のソースコードが解説されており、理解の助けになりました。