switch/if-elseif分岐をインターフェースとポリモーフィズムで置き換える

Contents

Replace switch/if-elseif branching with interfaces and polymorphism when appropriate. (適切な場合、switch/if-elseif分岐をインターフェースとポリモーフィズムで置き換える)

解説

型や状態による分岐が多数存在すると、新しい型を追加する際にすべての分岐を更新する必要があり、変更が困難になります。インターフェースとポリモーフィズムを使用することで、Open-Closed原則に従った拡張可能な設計が実現されます。新しい型を追加する際、既存のコードを変更せずに済むため、バグの混入リスクが減少します。ただし、単純な分岐まで無理に抽象化する必要はありません。

具体例

// 悪い例(型による分岐が多数)
func CalculateShipping(orderType string, weight float64) float64 {
    if orderType == "standard" {
        return weight * 10
    } else if orderType == "express" {
        return weight * 20
    } else if orderType == "overnight" {
        return weight * 30
    } else if orderType == "international" {
        return weight * 50
    }
    return 0
}

func GetDeliveryDays(orderType string) int {
    if orderType == "standard" {
        return 5
    } else if orderType == "express" {
        return 2
    } else if orderType == "overnight" {
        return 1
    } else if orderType == "international" {
        return 10
    }
    return 0
}

// 良い例(ポリモーフィズム使用)
type ShippingMethod interface {
    CalculateShipping(weight float64) float64
    GetDeliveryDays() int
}

type StandardShipping struct{}

func (s StandardShipping) CalculateShipping(weight float64) float64 {
    return weight * 10
}

func (s StandardShipping) GetDeliveryDays() int {
    return 5
}

type ExpressShipping struct{}

func (e ExpressShipping) CalculateShipping(weight float64) float64 {
    return weight * 20
}

func (e ExpressShipping) GetDeliveryDays() int {
    return 2
}

type OvernightShipping struct{}

func (o OvernightShipping) CalculateShipping(weight float64) float64 {
    return weight * 30
}

func (o OvernightShipping) GetDeliveryDays() int {
    return 1
}

// 新しいタイプを追加しても既存コードは変更不要
type InternationalShipping struct{}

func (i InternationalShipping) CalculateShipping(weight float64) float64 {
    return weight * 50
}

func (i InternationalShipping) GetDeliveryDays() int {
    return 10
}

// 使用例
func ProcessOrder(method ShippingMethod, weight float64) {
    cost := method.CalculateShipping(weight)
    days := method.GetDeliveryDays()
    fmt.Printf("Cost: %.2f, Days: %d\n", cost, days)
}

参考リンク

Show Text to Share
switch/if-elseif分岐をインターフェースとポリモーフィズムで置き換える
https://www.tricrow.com/core/coding-standard/polymorphism-over-branching.html
この記事を書いた人
T.Nakamura
T.Nakamura
AIが大好きなクラウドエンジニア。IT業界歴10年以上。標準化と効率化を追求している。技術ネタを発信中。フォローお気軽にどうぞ!フォローはこちら

カテゴリ

タグ