iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
1
自我挑戰組

Let's Eat GO ! 實務開發雜談by Golang系列 第 22

Day22 .[心得與討論篇] struct 設計解析 - 以melody package (2)

承上一篇,我們從melody.Session 開始做研究。

step1 . 找出業務主體的struct

首先找到它的位置。

// Session wrapper around websocket connections.
type Session struct {
	Request *http.Request
	Keys    map[string]interface{}
	conn    *websocket.Conn
	output  chan *envelope
	melody  *Melody
	open    bool
	rwmutex *sync.RWMutex
}

ok,Session 是一個struct的型態,我們來看一下內容有什麼,主要抓可能也是struct的東西來看就好了。

下面這幾個是別的package的東西,就先乎略不看。

*http.Request
*websocket.Conn
*sync.RWMutex

值得在乎的就只剩兩者,envelope先不管是被當作channel使用的型態。

output  chan *envelope
melody  *Melody

這兩個結構分別放在以下檔案

envelop.go

type envelope struct {
	t      int
	msg    []byte
	filter filterFunc
}

melody.go

type Melody struct {
	Config                   *Config
	Upgrader                 *websocket.Upgrader
	messageHandler           handleMessageFunc
	messageHandlerBinary     handleMessageFunc
	messageSentHandler       handleMessageFunc
	messageSentHandlerBinary handleMessageFunc
	errorHandler             handleErrorFunc
	closeHandler             handleCloseFunc
	connectHandler           handleSessionFunc
	disconnectHandler        handleSessionFunc
	pongHandler              handleSessionFunc
	hub                      *hub
}

再繼續尋了一遍,有相關又是struct的結構,有*Config 和 *hub

Config

// Config melody configuration struct.
type Config struct {
	WriteWait         time.Duration // Milliseconds until write times out.
	PongWait          time.Duration // Timeout for waiting on pong.
	PingPeriod        time.Duration // Milliseconds between pings.
	MaxMessageSize    int64         // Maximum size in bytes of a message.
	MessageBufferSize int           // The max amount of messages that can be in a sessions buffer before it starts dropping them.
}

hub

type hub struct {
	sessions   map[*Session]bool
	broadcast  chan *envelope
	register   chan *Session
	unregister chan *Session
	exit       chan *envelope
	open       bool
	rwmutex    *sync.RWMutex
}

step 2 . 根據step1探查的結果,整理情報,初步理解業務關係

我們總共找到5個struct,此時就可以來猜測它們的關係了。

  1. session --> 關心 melody,envelope。
  2. envelope --> 什麼都不關心,也沒method,暫時視為資料存放用途為主。
  3. melody --> 關心 Config和hub。
  4. Config --> 什麼都不關心,也沒method,暫時視為資料存放用途為主。
  5. hub --> 關心envelope和Session。

envelope 和 Config分析起來,只是個資料儲存用途,我們就不是為業務主體,而且只關心業務主體。

於是重新再整理,業務主體有如下:

  1. session --> 關心 melody。
  2. melody --> 關心 hub。
  3. hub --> 關心 Session。

到這邊,發現很有趣的狀況,因為Session是我們直接接觸到的最末端型態,Session應該在下游,而melody應該在最上游。

關係是

melody --> hub --> Session

下面的不知上面的,如hub不知道有melody,session不知道有hub,但是最下游的Session,卻又能直接關心最上游的melody。

 Session --> melody

三者業務主體好比銜尾蛇一樣,頭咬著對方尾巴,卻不知道尾巴被誰咬著,但整體卻連接在一起,形成一個圓圈。

為什麼有這樣的設計呢?

其實並不是melody這個package特地稀奇古怪的這樣寫,source code或其他一樣open source也常出現的結構,起初筆者還不太懂這種模式和背後的用意,覺得十分困惑。

其實也不是太難的東西,但沒人點破實在是個麻煩的障礙,下篇筆者試著來為大家分享如何解釋這樣的設計,希望能夠幫助一些跟筆者當初一樣,遇到卡關障礙的開發者。


上一篇
Day21 .[心得與討論篇] struct 設計解析 - 以melody package (1)
下一篇
Day23 .[心得與討論篇] struct 設計解析 - 以melody package (3)
系列文
Let's Eat GO ! 實務開發雜談by Golang30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言