MVC的概念其實大家都滾瓜爛熟了,但卻也是一個大家跨框架時最好下手認識框架的觀念
MVC由Model(模型)-View(畫面)-Controller(控制器)組成
進入軟體業一年,我想用這樣的方式來解釋MVC
結論:mvc中model扮演的角色是模擬現實物件,controller負責處理使用者請求,view則負責呈現數據給使用者
這樣子介紹,我希望你們可以把model與controller和view分開,model是一個獨立的個體,因為他是一個獨立模擬出來的物件
再來我們懂MVC後,接下來要談談發送請求到發送請求後怎麼與MVC對接
當使用者發送request後,伺服器端需要有路由器去分配請求路徑該派發到哪一個多工器(controller)處理,在多工器可能會需要與資料庫對接,此時就需要model負責與資料庫溝通,多工器處理完成後可能需要畫面(view)渲染
http是一種用於在客戶端和伺服器端之間傳遞數據的協議,我們要理解http構建的過程主要關注兩個端口,client的客戶端及server的伺服器端
基本流程是這樣,
我們需要一個ServeMux
類型,他是go中的路由分派器->對ServeMux
產生實例->並用這個實例執行HandleFunc
ServeMux
類型
net/http
套件中是一個HTTP 請求多路徑器(multiplexer)ServeMux
是一個結構(struct),內部有方法和屬性,其中一個方法就是HandleFunc
,他用於將特定的路徑關聯到處理器函數type ServeMux struct {
// ... 其他屬性
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
// 這裡是將模式與處理函數關聯起來的具體實作
}
DefaultServeMux
net/http
套件提供了一個預設的 ServeMux
實例,稱為 DefaultServeMux
ServeMux
,供你直接使用http.HandleFunc
函數http.HandleFunc
DefaultServeMux
,所以也可以說當你呼叫http.HandleFunc
時其實就是直接對DefaultServeMux
的HandleFunc
呼叫
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
我們有了路由處理器後,就要來開始監聽請求,在Go中會使用net/http
提供的http.ListenAndServe
來監聽請求,那這個function做了什麼事呢,下面我們來分析一下
net.Listen
函數,伺服器開始在指定的地址和端口上監聽TCP
連接以上介紹了路由及controller的處理
我們來舉兩個簡單的例子
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
addr := "localhost:8080"
fmt.Printf("Starting server on %s...\n", addr)
err := http.ListenAndServe(addr, nil)
if err != nil {
panic(err)
}
}
package main
import (
"fmt"
"net/http"
)
type HelloWorldHandler struct{}
func (h *HelloWorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
handler := &HelloWorldHandler{}
http.Handle("/", handler)
addr := "localhost:8080"
fmt.Printf("Starting server on %s...\n", addr)
err := http.ListenAndServe(addr, nil)
if err != nil {
panic(err)
}
}
上面兩個例子的差別在於,第二個例子的handler函數是先實現了http.Handler接口的物件,而第一個例子沒有
http.Handle
http.Handler
接口的物件。http.Handler
接口(即有一個ServeHTTP
方法),可以直接使用此方法將該物件註冊為一個路由的處理程序http.HandleFunc
func(w http.ResponseWriter, r *http.Request)
http.Handler
接口,可以使用此方法。實際上,http.HandleFunc
在內部創建一個臨時的http.Handler
物件來包裝給定的函數
func handlePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "This is the page handler.")
}
http.HandleFunc("/", handlePage)