不必要にゲッターを使わない
Contents
Don’t use getters unnecessarily. (不必要にゲッターを使わない)
解説
すべてのフィールドに機械的にゲッターを用意することは、カプセル化の本質を見失った形式的な実装です。ゲッターは、外部に公開する必要がある情報に対してのみ提供すべきです。不必要なゲッターは、内部実装の詳細を露出させ、クラスの責任を不明確にします。本当に必要な場合のみゲッターを作成することで、適切なカプセル化が実現され、変更の影響範囲が限定されます。
具体例
// 悪い例(すべてのフィールドにゲッターを用意)
type Order struct {
id string
customerID string
items []Item
subtotal float64
tax float64
shipping float64
createdAt time.Time
updatedAt time.Time
}
// すべてのフィールドに機械的にゲッターを用意
func (o *Order) ID() string { return o.id }
func (o *Order) CustomerID() string { return o.customerID }
func (o *Order) Items() []Item { return o.items }
func (o *Order) Subtotal() float64 { return o.subtotal }
func (o *Order) Tax() float64 { return o.tax }
func (o *Order) Shipping() float64 { return o.shipping }
func (o *Order) CreatedAt() time.Time { return o.createdAt }
func (o *Order) UpdatedAt() time.Time { return o.updatedAt }
// 良い例(本当に必要なゲッターのみ提供)
type Order struct {
id string
customerID string
items []Item
subtotal float64
tax float64
shipping float64
createdAt time.Time
updatedAt time.Time
}
// 外部に公開が必要な情報のみゲッターを提供
func (o *Order) ID() string {
return o.id
}
func (o *Order) CustomerID() string {
return o.customerID
}
// 計算されたtotalのみ公開(内訳は公開しない)
func (o *Order) Total() float64 {
return o.subtotal + o.tax + o.shipping
}
// ItemsのゲッターではなくItemの数のみ公開
func (o *Order) ItemCount() int {
return len(o.items)
}
// さらに良い例(ドメインメソッドとして提供)
func (o *Order) IsExpired() bool {
return time.Since(o.createdAt) > 30*24*time.Hour
}
func (o *Order) CanBeCancelled() bool {
return time.Since(o.createdAt) < 24*time.Hour
}
// 内部計算フィールドは完全に隠蔽
func (o *Order) calculateSubtotal() float64 {
total := 0.0
for _, item := range o.items {
total += item.Price * float64(item.Quantity)
}
return total
}
func (o *Order) calculateTax() float64 {
return o.subtotal * 0.1
}
参考リンク
不必要にゲッターを使わない https://www.tricrow.com/core/coding-standard/no-unnecessary-getters.html

