【Go】インタフェースを使用した実装の隠蔽について

今回はGoでインタフェースを使用した実装の隠蔽について調べてみた。

実装の隠蔽

外部に実装を公開させない。例えばメンバ変数は外部に公開せず、その操作をするための関数だけ公開する。

実装

// 呼び出し側
func bakedpan() {
	bp := New()
	pan := Pan{Name: "syokupan"}
	bp.Bake(pan)
	bp.Hello()
}
package main

import "fmt"

// 操作する対象の構造体
type Pan struct {
	Name string
}

// interfaceとして公開
type Baker interface {
	Bake(p Pan)
}

// プライベートな構造体
type baker struct {
}

// 初期化かつ Bakerインタフェース型を返す
func New() Baker {
	return &baker{}
}

// baker に対してBake を実装
func (b *baker) Bake(p Pan) {
	fmt.Println("Baked " + p.Name)
}

// baker に対してHello を実装
func (b *baker) Hello() {
	fmt.Println("Hello")
}

ポイント

New() の返り値

New() で返すのは、プライベートなbaker型です。プライベートな型が返ってきてもよいのかという点が気になります。これは、特に問題ありません。というのも、呼び出し側は、Bakerインタフェースに合致したオブジェクトが返ってきていること以外関知しないからです。

bakerに対する操作

例えば、今回はbakerに2つの関数を実装しています。Bake()とHello()です。両方共bakerに対して実装しています。呼び出し側では、bp := New()でオブジェクトを生成し、各関数を呼び出していますが、Bake()は問題なく実行できますが、Hello()は実行できません。


これは、プライベートなbaker型に対しての操作はインタフェース経由でのみ実行できるようにしているためです。今回インタフェースで公開しているのはBake()だけなので、それ以外の関数を実行することはできません。つまり、外部からみたらbaker型の実装は隠蔽されており、公開されているBake()経由でのみ操作ができるということです。

感想

こうすることで、インタフェースに基づいてのみ操作がされ、シンプルな状態に保てるはず