Go 代碼應用設計模式: 迭代器模式、中介者模式、觀察者模式

今天我們繼續講解行爲模式中的迭代器模式

迭代器模式是一種便於遍歷各種數據結構,而無需關注其底層實現的的實現方式。例如我們經常用的 slice、map 等使用 for range 方式均可遍歷,而 for range 則是通過迭代器模式實現的。

在我們開發過程中,由於語言提供的數據結構已經可以適用於 90% 以上的場景,同時也提供了其遍歷的方法。所以我們在開發過程中自己去實現迭代器的場景並不常見。我們來看下通過 Go 語言實現迭代器算法的示例:

intCollection 爲需要遍歷的數據結構,intIterator 爲該結構的迭代器:

type intCollection struct {
  nums []int
}
type intIterator struct {
  index int
  nums  []int
}
func (u *intCollection) createIterator() *intIterator {
  return &intIterator{
    nums: u.nums,
  }
}

迭代器需要有判斷下個節點是否存在和獲取下一個節點內容的方法:

func (u *intIterator) hasNext() bool {
  if u.index < len(u.nums) {
    return true
  }
  return false
}
func (u *intIterator) getNext() int {
  if u.hasNext() {
    n := u.nums[u.index]
    u.index++
    return n
  }
  panic("out of range")
}

接下來我們講解行爲模式中的中介者模式

中介者模式把錯綜複雜的類與類的關係交給一箇中間對象來管理,而普通對象只需要關注自己的行爲,無需去關注其他對象的行爲。

在生活中例如機場的塔臺和所有的飛機,飛機只需要給塔臺發送信號,而在塔臺對信號進行處理後,會調度其他相關的飛機起落、飛行軌跡。此時發送信號的飛機間接的與其他飛機發生了關聯,而無需關注是和具體的哪些飛機發生關聯。

我們通過代碼來實現上述案例:

type Plane struct {
  flightNumber string //航班號
  c            *ControllerTower
}
type ControllerTower struct {
  planes []*Plane
}
func (p *Plane) Send() {
  fmt.Println("plane send signal")
  p.c.Receive()
}
func (p *Plane) Receive() {
  fmt.Println("plane receive signal")
}
func (c *ControllerTower) Send(p *Plane) {
  fmt.Println("tower send signal")
  p.Receive()
}
func (c *ControllerTower) Receive() {
  fmt.Println("tower receive signal")
}

無論多少臺飛機直接在同一時段可能產生關聯,飛機本身是對塔臺充分信任的,只需要和塔臺進行交互。但是這也是中介者模式一大缺點,當飛機越來越多,關係越來越複雜,ControllerTower 將會成爲一個超級大的類。

我們緊接着瞭解下觀察者模式

觀察者模式爲一種訂閱通知機制,在某個對象發生狀態變更時通知其他的對象。兩者的代碼結構類似。

觀察者模式與中介者模式邏輯是類似的,我們也可以理解爲飛機訂閱了塔臺,所以收到了通知。但是觀察者比中介要簡單多了,觀察者只需要通知給所有的訂閱者,而中介者內部有着複雜的邏輯關係。

其不同點在於 塔臺收到消息後,是通知所有的飛機還是通知一部分飛機,代碼邏輯如下:

//通知所有訂閱的對象
func (c *ControllerTower) Receive() {
  for _, p := range c.planes {
    p.Receive()
  }
  fmt.Println("tower receive signal")
}
//通過邏輯處理獲取需要通知的對象
func (c *ControllerTower) Receive() {
  for _, p := range getPlanes() {
    p.Receive()
  }
  fmt.Println("tower receive signal")
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/DjnqPh5QI5s0grfeeprrSg