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を更新するだけです。
チャレンジ
簡単Factoryパターンを使ってドキュメント変換システムを構築しましょう!対象のformatに基づいてさまざまなドキュメントconverterを生成するfactoryを作成し、クライアントコードが統一されたinterfaceを通じて任意のconverterを扱えるようにします。
コードを2つのファイルに分けて整理します。
converter.go: converter interfaceと具体的な実装をDefineします。Converterinterfaceを作成し、ドキュメントのcontentを受け取り、変換後の出力を返すConvert(content string) stringmethodを持たせます。3つのconverter typeをImplementします。
PDFConverter: そのConvertmethodはPDF: [content]を返しますHTMLConverter: そのConvertmethodはHTML: <p>[content]</p>を返しますMarkdownConverter: そのConvertmethodはMD: # [content]を返します
NewConverter(format string) Converterfactory functionを作成し、format string(pdf、html、またはmarkdown)に基づいてappropriateなconverterを返します。認識できないformatの場合は、defaultとしてPDFConverterを返します。main.go: factoryを使用してconverterを作成し、ドキュメントを処理します。format typeとドキュメントのcontentをReadします。factoryを使用してappropriateなconverterを作成し、その後contentを変換してresultをprintします。
次の入力が提供されます。
- 1行目: format type(
pdf、html、markdown、またはその他の文字列) - 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 Notesmain 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)
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー自分で練習してみよう: Goオンラインコンパイラ