Go言語のインターフェース設計パターン集!現場で役立つ使い方
先生と生徒の会話形式で理解しよう
生徒
「先生、Go言語で現場でよく使われるインターフェースの設計パターンってありますか?」
先生
「はい、インターフェースを上手に使うと、コードの柔軟性や再利用性が高くなります。今日は代表的な設計パターンをいくつか紹介します。」
生徒
「具体的にはどのように使うんですか?」
先生
「それでは、基本的なパターンと使い方を順番に見ていきましょう!」
1. Strategyパターン
Strategyパターンは、処理のアルゴリズムをインターフェースで抽象化し、動的に切り替える設計です。例えば、支払い方法をクレジットカードやPayPalなどで切り替えたい場合に便利です。
type PaymentStrategy interface {
Pay(amount int)
}
type CreditCard struct{}
func (c CreditCard) Pay(amount int) { fmt.Println("クレジットカードで支払い:", amount) }
type PayPal struct{}
func (p PayPal) Pay(amount int) { fmt.Println("PayPalで支払い:", amount) }
func Checkout(p PaymentStrategy, amount int) {
p.Pay(amount)
}
Checkout関数に任意のPaymentStrategyを渡すことで、支払い方法を簡単に切り替えられます。
2. Adapterパターン
Adapterパターンは、異なるインターフェースを統一して扱うためのパターンです。古いAPIと新しいAPIをつなぐ場合などに役立ちます。
type OldPrinter struct{}
func (o OldPrinter) PrintOld(s string) { fmt.Println("旧プリント:", s) }
type Printer interface {
Print(s string)
}
type PrinterAdapter struct {
Old OldPrinter
}
func (p PrinterAdapter) Print(s string) {
p.Old.PrintOld(s)
}
Printerインターフェースを使うことで、古いプリンタでも新しいコードから統一的に呼び出せます。
3. Decoratorパターン
Decoratorパターンは、既存の機能に新しい機能を追加するパターンです。インターフェースを利用すると柔軟に拡張できます。
type Notifier interface {
Send(message string)
}
type EmailNotifier struct{}
func (e EmailNotifier) Send(message string) { fmt.Println("メール送信:", message) }
type SMSDecorator struct {
Notifier
}
func (s SMSDecorator) Send(message string) {
s.Notifier.Send(message)
fmt.Println("SMS送信:", message)
}
EmailNotifierにSMS送信機能を後付けすることができます。
4. Compositeパターン
Compositeパターンは、単一のオブジェクトとオブジェクトの集合を同じインターフェースで扱うパターンです。ツリー構造のデータを操作するときに便利です。
type Component interface {
Operation()
}
type Leaf struct {
Name string
}
func (l Leaf) Operation() { fmt.Println("Leaf:", l.Name) }
type Composite struct {
Children []Component
}
func (c Composite) Operation() {
for _, child := range c.Children {
child.Operation()
}
}
Compositeを使うと、単一の要素と複数の要素を同じ操作で扱えます。
5. 実務での活用ポイント
- インターフェースは「何をするか」を定義し、「どうやるか」は具体的な型に任せる
- Strategyパターンで処理の切り替えを簡単にする
- Adapterパターンで古いコードや外部ライブラリとの互換性を確保
- Decoratorパターンで機能を拡張し、Compositeパターンで構造化されたデータを統一的に操作
- 現場では、コードの柔軟性と保守性を高めるためにパターンを組み合わせて使う