5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Goのインタフェースとその実装、およびstructへの埋め込み

Last updated at Posted at 2014-08-12

RubyのModuleのように

  • インタフェースの実装をStructに埋め込む
i_f.go
package main

import "fmt"

// 料理を作るI/F
type Cooker interface {
  Cook() string
}

// 塗るI/F
type Painter interface {
  Paint() string
}

// 働くI/F
type Worker interface {
  Work() string
}

// 家庭料理を作ることによってCookerI/Fを実装
type HomeCooker struct{}

func (c *HomeCooker) Cook() string {
  return "簡単な料理を作ります。"
}

// 日曜大工レベルでPainterI/Fを実装
type SundayPainter struct{}

func (p *SundayPainter) Paint() string {
  return "日曜大工レベルでペンキを塗ります。"
}

// 会社で働いてWorkerI/Fを実装
type OfficeWorker struct{}

func (w *OfficeWorker) Work() string {
  return "会社で仕事をします。"
}

/*
*  お父さんStructは
*    CookerI/Fの任意の実装
*    PainterI/Fの任意の実装
*    WorkerI/Fの任意の実装
*  をコンポジションする
 */
type Father struct {
  Name string
  Cooker
  Painter
  Worker
}

// ふつうのお父さん
func NewGenericFather() *Father {
  return &Father{
    "ふつうのお父さん",
    // 一般的な実装を持っている
    &HomeCooker{},
    &SundayPainter{},
    &OfficeWorker{},
  }
}

// クッキングパパ
type CookingPapa struct {
  Name string
  Painter
  Worker
}

func NewCookingPapa() *CookingPapa {
  return &CookingPapa{
    "クッキングパパ",
    // CookerI/Fは自分自身で実装する
    // PainterI/FとWorkerI/Fは一般的な実装を借りる
    &SundayPainter{},
    &OfficeWorker{},
  }
}

func (cp *CookingPapa) Cook() string {
  return "なんか工夫したりしてすごい料理を作ります。"
}

/*
* いろんなことをする時に
* Fatherオブジェクトではなく
* 何かしたいことが出来る(責務を持った)
* interfaceを引数に取る
 */
func MakeDinner(c Cooker) string {
  return c.Cook()
}

func RepairRoof(p Painter) string {
  return p.Paint()
}

func GetMoney(w Worker) string {
  return w.Work()
}

func main() {
  gf := NewGenericFather()
  fmt.Println(gf.Name)
  fmt.Println("- ", MakeDinner(gf))
  fmt.Println("- ", RepairRoof(gf))
  fmt.Println("- ", GetMoney(gf))

  cp := NewCookingPapa()
  fmt.Println(cp.Name)
  fmt.Println("- ", MakeDinner(cp))
  fmt.Println("- ", RepairRoof(cp))
  fmt.Println("- ", GetMoney(cp))
}
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?