Saturday, March 12, 2016

Golang Interface Explanation

golangInterface

The Explanation for Golang's Interface

Golang的Interface一直以來都處在一種模糊的想法,無法去確定為什麼需要這樣的東西,而又對程式帶來什麼樣的好處。 我重新思考了一下Interface並藉此記錄下來。 Interface至少有兩個用法,
1. 對變數不假設型態,比如map的Docker type。這是很容易了解的,所以不需要做太多的解釋。
2. 對Method的抽象(abstract)組合(composition)。
最主要我想了解的是第二個用法。

我們在Google上常常會看到類似以下範例來解釋Interface。

package main

import (
    "fmt"
)

type Geometry interface {
    area() (error, float64)
}

type Rect struct {
    width  float64
    height float64
}

func (R Rect) area() (error, float64) {
    return nil, R.width * R.height * 2
}

type Circle struct {
    radius float64
}

func (C Circle) area() (error, float64) {
    return nil, C.radius * C.radius * 3.14
}

func Measure(g Geometry) (error, float64) {
    _, ss := g.area()
    fmt.Println(ss)
    return nil, ss
}


func main() {
    fmt.Println("hah")
    rr := Rect{width: 3, height: 2}
    Measure(rr)
    cc := Circle{radius: 2}
    Measure(cc)
}

傳統的做法,可能在main function中直接使用Rect.area()Circle.area()來計算area。
而Interface就是想取代這樣的概念,能否藉由一個統一的接口來獲得area,比如Measure function,透過此統一接口(interface), Measure(Rect) or Measure(Circle),來提供Service。
這裏我強調Service正是我體悟到Interface的目的,如果你想懂了Service的概念,應該這篇文章就讀到此處即可了。
其實跳出來想,如果有一個Service可以用任何變數型態帶入,都會return相應的結果,這樣是不是很棒呢?! 這就是我強調Service的由來,而此概念可以透過Interface來完成。
當然,對於Programmer來講他除了要寫傳統的代碼架構,他還得花時間多些一層Interface提供服務。
而對User來講,他只看到Data本身,變數需要填入的數值外,就是統一接口(interface)所提供的Service。

為了更清楚的描述,花了半小時畫了如下圖。

透過上圖,我們可以清楚地看到,透過Interface,Programmer的抽象化Method後,User可以得到單一入口的Service。
基本上Programmer本身是需要做更多的事情的,但對User來講, 如何調用函數的問題,就被淡化掉了,因為變成了統一的接口(Measure Function)。 上圖簡單的說就是,Programmer提供了Data與Service內容,給User,而User就是填滿Data並放入統一的接口。

上述程式,主要是寫在main中,這有一個缺點,你會看不到Interface是如何提供Service,並讓User更簡單的使用你所提供的Lib。
假設Rect,Circle,與Geometry Interface是寫在一個Lib上,並透過go get下載得到。當你在使用此Lib,我們暫時叫做shape的lib。 我們會import "shape"並使用它透過shape.rect{3,2},並直接使用shape.Measure()來調用。任何型態都可放入shape.Measure()中,比如shape.Measure(Rect),透過這樣的瞭解,我相信,Interface的目的就更容易凸顯出來了。
此外此代碼部分,你可以看到Rect.area()其實是個private函數,User是無法使用的,只能透過Measure來使用,這也是從傳統走入Inteface的一個差別,當然,你已可以改成大寫,就是個Public函數了。

最後,我們還沒定義何謂User,何謂Programmer。 在這樣的範例中,我定義的programmer其實是指的撰寫shape的人,而user是用go get下載,準備使用此Lib的人。

對Interface的結論

對User而言,只會看到Data與Service。
對Programmer而言不只要寫傳統的定義,還得從新定義Interface所要帶來的Service。

No comments:

Post a Comment