basyura's blog

あしたになったらほんきだす。

Go - 差分プログラミング

こんな構成があったとして

  • IHoge を実装した Hoge と Fuga をファクトリーメソッドなどで生成対象を切り替えたい
  • Hoge の差分だけを Fuga に実装したい

よくあるケース。 Go の場合は Fuga に Hoge を埋め込めばだいたいできるのだけど、外から呼ばれたメソッド内で override したメソッドを呼ぶようなことができない。

じゃあどうするか。

切り替えたいことは変数に出しておいて init で登録し、Hoge 内で切り替えて呼び出す。

package main

import (
    "fmt"
    . "inherit/lib"
)

func main() {
    keys := []string{"hoge", "fuga"}
    for _, key := range keys {
        h := newHoge(key)
        fmt.Println(h.Do(key))
    }

    //=> hoge
    //=> fuga!!
}

// factory metohd
func newHoge(key string) IHoge {
    if key == "fuga" {
        return Fuga{}
    }

    return Hoge{}
}
package lib

type Hoge struct {
}

var funcs = map[string]func(key string) string{}

func (h Hoge) Do(key string) string {

    if f, ok := funcs[key]; ok {
        return f(key)
    }

    return "hoge"
}
package lib

func init() {
    funcs["fuga"] = func(key string) string {
        return key + "!!"
    }
}

type Fuga struct {
    Hoge
}

としたらできるけど、アンチパターン臭がすごいなぁ・・・。