Menu
Coddy logo textTech

Factory パターン

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 87/107。

Factory パターンは、オブジェクトの生成を独立した関数またはメソッドに委譲します。これにより、生成ロジックを公開せずにインスタンスを作成できます。インスタンス数を制御する Singleton とは異なり、Factory は入力パラメーターに基づく柔軟なオブジェクト生成に重点を置きます。

Goでは、factoryは通常interface typeを返すfunctionであり、統一されたAPIを通じて異なる具体的なtypeを作成できます。

type Notifier interface {
    Send(message string) string
}

type EmailNotifier struct{}
type SMSNotifier struct{}

func (e EmailNotifier) Send(message string) string {
    return "Email: " + message
}

func (s SMSNotifier) Send(message string) string {
    return "SMS: " + message
}

func NewNotifier(notifierType string) Notifier {
    switch notifierType {
    case "email":
        return EmailNotifier{}
    case "sms":
        return SMSNotifier{}
    default:
        return EmailNotifier{}
    }
}

ファクトリ関数 NewNotifier は、どの具象型を作成するかという判断をカプセル化します。クライアントコードは Notifier インターフェースのみを使用し、具体的な実装を意識する必要がありません。

notifier := NewNotifier("sms")
result := notifier.Send("Hello!")  // "SMS: Hello!"

このパターンは、実行時の条件に基づいてオブジェクトをcreateする必要がある場合、複雑な初期化ロジックを一元化したい場合、またはクライアントコードを変更せずに新しい型を簡単に追加する必要がある場合に力を発揮します。interfaceを実装する新しいstructを追加し、factory functionを更新するだけです。

challenge icon

チャレンジ

簡単

Factoryパターンを使ってドキュメント変換システムを構築しましょう!対象のformatに基づいてさまざまなドキュメントconverterを生成するfactoryを作成し、クライアントコードが統一されたinterfaceを通じて任意のconverterを扱えるようにします。

コードを2つのファイルに分けて整理します。

  • converter.go: converter interfaceと具体的な実装をDefineします。

    Converter interfaceを作成し、ドキュメントのcontentを受け取り、変換後の出力を返すConvert(content string) string methodを持たせます。

    3つのconverter typeをImplementします。

    • PDFConverter: そのConvert methodはPDF: [content]を返します
    • HTMLConverter: そのConvert methodはHTML: <p>[content]</p>を返します
    • MarkdownConverter: そのConvert methodはMD: # [content]を返します

    NewConverter(format string) Converter factory functionを作成し、format string(pdfhtml、またはmarkdown)に基づいてappropriateなconverterを返します。認識できないformatの場合は、defaultとしてPDFConverterを返します。

  • main.go: factoryを使用してconverterを作成し、ドキュメントを処理します。

    format typeとドキュメントのcontentをReadします。factoryを使用してappropriateなconverterを作成し、その後contentを変換してresultをprintします。

次の入力が提供されます。

  • 1行目: format type(pdfhtmlmarkdown、またはその他の文字列)
  • 2行目: 変換するドキュメントのcontent

例えば、次の入力が与えられた場合:

html
Welcome to Go Programming

出力は次のようになります。

HTML: <p>Welcome to Go Programming</p>

また、次の入力が与えられた場合:

markdown
Chapter One

出力は次のようになります。

MD: # Chapter One

また、次の入力が与えられた場合:

pdf
Annual Report 2024

出力は次のようになります。

PDF: Annual Report 2024

また、次の入力が与えられた場合:

docx
Meeting Notes

出力は次のようになります。

PDF: Meeting Notes

main codeが特定のconverter typeについて知る必要がないことに注目してください。main codeはfactoryにconverterを要求し、interfaceを使用するだけです。これにより、クライアントコードを変更せずに、後から新しいformatを簡単に追加できます!

自分で試してみよう

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// フォーマットタイプを読み取る
	scanner.Scan()
	format := scanner.Text()
	
	// ドキュメントの内容を読み取る
	scanner.Scan()
	content := scanner.Text()
	
	// TODO: ファクトリーを使用して適切なコンバーターを作成する
	// TODO: コンテンツを変換して結果を出力する
	
	fmt.Println(result)
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ