saeki’s blog

The limits of my code mean the limits of my world.

GoFデザインパターン ~Adapterパターン~

こちらを読みながら進める。

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

Adapterパターンとは

すでに存在するモジュールと必要なAPIとの間にAdapterを挟むことで、元のコードに手を加えることなくAPIを満たすことできる、というがAdapterパターン。
Adapterは必要となるAPIであるインターフェースを実装し、継承または委譲によってメソッドの中でAdapteeであるモジュールを使用する。

f:id:t_saeki:20190630215128p:plain

実装

増補改訂版Java言語で学ぶデザインパターン入門で使われてる本棚の例をGoで実装してみる。
Adapteeであるbannerを使って、Adapterインターフェースを満たすためにBannerAdapterを実装する

ディレクトリ構成は以下

├── banner
│   ├── banner.go
├── banner_adapter
│   ├── banner_adapter.go
└── main.go

Adaptee

package banner

import "fmt"

type Banner struct {
    Str string
}

func (b *Banner) WithParen() string {
    return fmt.Sprintf("(%s)", b.Str)
}

func (b *Banner) WithAster() string {
    return fmt.Sprintf("*%s*", b.Str)
}

Adapter

Clientが必要とするAdapterインターフェース

type Adapter interface {
    GetWeak() string
    GetStrong() string
}

BannerAdapterの実装

package banner_adapter

import "github.com/saekis/go-design-pattern/2_adapter/banner"

type Adapter interface {
    GetWeak() string
    GetStrong() string
}

type bannerAdapter struct {
    banner banner.Banner
}

func NewBannerAdapter(str string) Adapter {
    return &bannerAdapter{banner: banner.Banner{Str: str}}
}

func (b *bannerAdapter) GetWeak() string {
    return b.banner.WithParen()
}

func (b *bannerAdapter) GetStrong() string {
    return b.banner.WithAster()
}

Main

Main実装

package main

import (
    "fmt"

    "github.com/saekis/go-design-pattern/2_adapter/banner_adapter"
)

func main() {
    b := banner_adapter.NewBannerAdapter("Hello")
    fmt.Println(b.GetWeak())
    fmt.Println(b.GetStrong())
}

実行結果

$ go run main.go 
(Hello)
*Hello*

クラス図

f:id:t_saeki:20190630220924p:plain

実装したもの

github.com