Go言語入門 / golang 入門 デザインパターンFactory Method

f:id:nasust:20161122141513p:plain The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/) CC3.0

こんにちはnasustです。 前回はデザインパターンのBuilderをGo言語/ golangでの実装を解説しました。 今回も、オブジェクト指向デザインパターンをGo言語 / golangでどうやって実現する解説したいと思います。

Factory Methodの実装

Wikipediaデザインパターンを参考にGo言語 / golangで実装しました。

Factory Method パターン - Wikipedia

package main

import (
    "fmt"
    "sort"
    "unicode/utf8"
)

type ComparatorFunc func(i, j int) bool

type CreateComparatorInterface interface {
    SetList([]string)
    CreateComparatorFunc() ComparatorFunc
}

type ListPrinter struct {
    CreateComparator CreateComparatorInterface
}

func (listPrinter *ListPrinter) PrintList(lists []string) {
    listPrinter.CreateComparator.SetList(lists)
    comparator := listPrinter.CreateComparator.CreateComparatorFunc()
    sort.Slice(lists, comparator)
    for _, item := range lists {
        fmt.Println(item)
    }
}

type DictionaryOrderComparator struct {
    items []string
}

func (comparator *DictionaryOrderComparator) SetList(items []string) {
    comparator.items = items
}

func (comparator *DictionaryOrderComparator) CreateComparatorFunc() ComparatorFunc {
    return func(i, j int) bool {
        return comparator.items[i] < comparator.items[j]
    }
}

type LengthOrderComparator struct {
    items []string
}

func (comparator *LengthOrderComparator) SetList(items []string) {
    comparator.items = items
}

func (comparator *LengthOrderComparator) CreateComparatorFunc() ComparatorFunc {
    return func(i, j int) bool {
        return utf8.RuneCountInString(comparator.items[i]) < utf8.RuneCountInString(comparator.items[j])
    }
}

func main() {
    items := []string{"いちご","もも","いちじく"}
 
    fmt.Println("五十音で表示:")
    dictionaryOrderPrinter := &ListPrinter{&DictionaryOrderComparator{}}
    dictionaryOrderPrinter.PrintList(items)
 
    fmt.Println("")
 
    fmt.Println("長さ順で表示:")
    lengthOrderPrinter := &ListPrinter{&LengthOrderComparator{}}
    lengthOrderPrinter.PrintList(items)
}

実行すると以下の様に表示します。

五十音で表示:
いちご
いちじく
もも

長さ順で表示:
もも
いちご
いちじく

WikipediaのFacotry Methodパターンでは文字列の配列をソートして表示するサンプルです。Factory Methodで比較用の関数を生成して入れ替えられる様になっています。

Go言語 / golangではsortパッケージSlice関数でFactory Methodを実装しました。注意なのがこの関数はGo1.8で追加される予定であることです。11月22日現在の最新のバージョンは1.7.3で、まだ使用できません。GitHubから最新のソースをビルドして使える様になります。

CreateComparatorInterfaceインターフェイスで、sort.Sliceに与える比較用のクロージャを生成して返すCreateComparatorFuncメソッド、そしてクロージャが比較対象の配列を使える様に"SetItem"メソッドを持っています。インターフェイスを実装して、クロージャ生成の関数を入れ替える事によって、ソートの結果が変化します。

ListPrinter構造体のPrintListメソッド実行時は、CreateComparatorInterfaceインターフェイスを実装した構造体のメソッドでクロージャを生成して、PrintListメソッド内部のsort.Sliceで使用されます。

インターフェイスを使用することで、Factory MethodパターンもGo言語 / golangで実装できました。 シンプルな実装で関数の処理を入れ替える場合はクロージャだけで対応できると思います。


Go言語 / golang 入門 目次に戻る

広告を非表示にする