技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

Singleton【Go】

オブジェクト指向デザインパターンである、Singletonを実装する例です。

type Menu struct {
    name  string
    price int
}

var mymenu *Menu = newMenu("未定", 0)    // 定義時に

func newMenu(name string, price int) *Menu {    // コンストラクタのように初期化処理。ただし、頭文字は小文字にして"private"扱いにする
    return &Menu{name: name, price: price}
}

func GetMenu() *Menu {    // getterを通して同じものを返す。初期化処理が"private"な代わりに、getterを"public"に
    return mymenu
}

func (menu *Menu) Assign(name string, price int) {
    menu.name = name
    menu.price = price
}

func main() {
    fmt.Println(*GetMenu())
    mymenu.Assign("スープ", 750)
    fmt.Println(*GetMenu())
}


Singletonを利用することで、マルチスレッドなどによって
インスタンス生成処理が同時に発生しそうな状況下でも、
インスタンスの生成は1度に限定されます。

getterをpublicな状態とすることで、プログラム全体で1つのインスタンスを共有することになります。
シンプルな設計につながりますが、一方で弊害もあるようです。
それはコード間に依存関係を生んでしまう、ということです。
特に「疎結合が前提」の単体テストではその影響が顕著になるとのことです。
(詳細は参考資料2番目を参照)

マルチスレッドを安全にこなす方法には、他にもMutexがありますので、
Singletonを使用する際には、事前によく検討するべきかもしれません。

参考

サルでもわかる 逆引きデザインパターン 第2章 逆引きカタログ ロジック編 Singleton(シングルトン)

プログラマが知るべき97のこと/シングルトンパターンの誘惑に負けない - Wikisource