各関数は100行以内に収める
Contents
Keep each function to 100 lines or fewer (logical lines; wrapped lines count as one). (各関数は100行以内に収める(論理行;折り返された行は1行とカウント))
解説
長い関数は、複数の責任を持っている可能性が高く、理解とテストが困難です。100行を超える関数は、処理を小さな関数に分割することで、可読性と再利用性が向上します。短い関数は、単一の責任を持ち、名前から目的が明確になります。論理行でカウントするため、コメントや空行、折り返しは複数行とはみなされません。適切な粒度の関数は、バグの発見と修正を容易にします。
具体例
// 悪い例(長すぎる関数 - 200行以上)
func ProcessOrder(order Order) error {
// バリデーション(30行)
if order.ID == "" {
return errors.New("order ID is required")
}
if order.CustomerID == "" {
return errors.New("customer ID is required")
}
// ... さらに20項目のバリデーション
// 在庫チェック(40行)
for _, item := range order.Items {
stock, err := db.GetStock(item.ProductID)
if err != nil {
return err
}
// ... 複雑な在庫ロジック
}
// 価格計算(40行)
subtotal := 0.0
for _, item := range order.Items {
subtotal += item.Price * float64(item.Quantity)
}
// ... 割引、税金、送料の計算
// 決済処理(40行)
// ... 決済ゲートウェイとの通信
// メール送信(30行)
// ... メール作成と送信
// データベース保存(20行)
// ... 複数テーブルへの保存
return nil
}
// 良い例(適切に分割された関数)
func ProcessOrder(order Order) error {
if err := validateOrder(order); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
if err := checkInventory(order.Items); err != nil {
return fmt.Errorf("inventory check failed: %w", err)
}
total, err := calculateOrderTotal(order)
if err != nil {
return fmt.Errorf("calculation failed: %w", err)
}
if err := processPayment(order.CustomerID, total); err != nil {
return fmt.Errorf("payment failed: %w", err)
}
if err := saveOrder(order); err != nil {
return fmt.Errorf("save failed: %w", err)
}
if err := sendConfirmationEmail(order); err != nil {
log.Printf("email failed: %v", err)
// メール失敗は注文処理を失敗させない
}
return nil
}
// 各関数は単一の責任を持ち、100行以内
func validateOrder(order Order) error {
if order.ID == "" {
return errors.New("order ID is required")
}
if order.CustomerID == "" {
return errors.New("customer ID is required")
}
// ... その他のバリデーション
return nil
}
func checkInventory(items []Item) error {
for _, item := range items {
if err := verifyStockAvailability(item); err != nil {
return err
}
}
return nil
}
func calculateOrderTotal(order Order) (float64, error) {
subtotal := calculateSubtotal(order.Items)
discount := calculateDiscount(order, subtotal)
tax := calculateTax(subtotal - discount)
shipping := calculateShipping(order)
return subtotal - discount + tax + shipping, nil
}
参考リンク
各関数は100行以内に収める https://www.tricrow.com/core/coding-standard/max-100-lines.html

