😽
動詞+名詞+Serviceで学ぶ!責務を1つに絞ったサービスクラス設計
責務とは「その人(クラス)が担当する仕事」のこと
プログラミングの世界でよく聞く「Service Objectの責務を1つに絞り込む」という原則。この「責務」って何でしょうか?
責務 = その人(クラス)が担当する1つの仕事
🏫 学校を例に考えてみよう!
✅ 良い例:係を分担している
- 図書係の花子ちゃん:本の整理、貸し出し管理だけを担当
- 掃除係の太郎くん:教室の掃除だけを担当
- 給食係の次郎くん:給食の配膳だけを担当
❌ 悪い例:係を分担せず一人でなんでもやる
- 三郎くん:図書の管理も、掃除も、給食配膳も、プリント配りも、花の水やりも全部やる
三郎くんは忙しすぎて、どの仕事も中途半端になってしまいますよね?
💻 プログラミングでの責務
❌ 悪い例:何でもユーザーサービス
class UserService
def call(user_params)
# 1. ユーザー作成
user = User.create!(user_params)
# 2. メール送信
UserMailer.welcome_email(user).deliver_now
# 3. ポイント付与
user.points.create!(amount: 100, reason: '新規登録')
# 4. SNS投稿
TwitterAPI.post("新しいユーザーが登録しました!")
# 5. 管理者に通知
AdminNotifier.new_user_registered(user)
# 6. ログ出力
Rails.logger.info "User created: #{user.id}"
# 7. キャッシュ更新
Rails.cache.delete('user_count')
user
end
end
問題点:
- メール送信でエラーが出たら、ユーザー作成も失敗する?
- SNS投稿機能を変更したら、ユーザー作成も影響を受ける?
- テストが難しい(全部の機能をテストしないといけない)
✅ 良い例:責務を分けたサービス
命名規則:「動詞 + 名詞 + Service」
# 🎯 責務1: ユーザー作成だけ
class CreateUserService
def call(user_params)
ActiveRecord::Base.transaction do
user = User.create!(user_params)
Rails.logger.info "User created: #{user.id}"
user
end
end
end
# 📧 責務2: ウェルカムメール送信だけ
class SendWelcomeEmailService
def call(user)
UserMailer.welcome_email(user).deliver_later
Rails.logger.info "Welcome email queued for user: #{user.id}"
end
end
# 🎁 責務3: 新規登録ポイント付与だけ
class GrantWelcomePointsService
def call(user)
user.points.create!(
amount: 100,
reason: '新規登録ボーナス'
)
Rails.logger.info "Welcome points granted to user: #{user.id}"
end
end
# 🐦 責務4: SNS投稿だけ
class PostSocialMediaMessageService
def call(message)
TwitterAPI.post(message)
Rails.logger.info "Posted to Twitter: #{message}"
rescue TwitterAPI::Error => e
Rails.logger.error "Twitter post failed: #{e.message}"
# SNSの失敗は他の処理に影響しない
end
end
# 🎼 責務5: 全体の流れを制御するだけ(指揮者のような役割)
class RegisterUserWorkflowService
def call(user_params)
# メインの処理(失敗したら全体が失敗)
user = CreateUserService.new.call(user_params)
# 副次的な処理(失敗しても登録は成功扱い)
begin
SendWelcomeEmailService.new.call(user)
GrantWelcomePointsService.new.call(user)
PostSocialMediaMessageService.new.call("新しいユーザーが登録しました!")
rescue StandardError => e
Rails.logger.error "Post-registration process failed: #{e.message}"
# エラーが起きても登録自体は成功
end
user
end
end
🤔 なぜ責務を1つに絞るのが良いの?
1. 📖 理解しやすい
悪い例: 「三郎くんは何をする人?」→「えーっと...何でもする人」
良い例: 「図書係の花子ちゃんは何をする人?」→「本の管理をする人!」
2. 🔧 壊れにくい
悪い例: 三郎くんが風邪で休んだら、全ての係の仕事が止まる
良い例: 図書係の花子ちゃんが休んでも、掃除係や給食係は普通に動く
3. 🧪 テストしやすい
悪い例: 三郎くんをテストするには、図書室も、掃除道具も、給食も全部用意が必要
良い例: 図書係のテストなら、本だけ用意すればOK
4. 🔄 再利用しやすい
悪い例: 三郎くんは他のクラスでは使えない(忙しすぎるから)
良い例: 図書係の花子ちゃんは、他のクラスの図書室でも活躍できる
📝 「動詞 + 名詞 + Service」命名規則
🎯 何をするかが一瞬で分かる
従来の命名:
UserManager # ユーザーを...管理?何を?
DataProcessor # データを...処理?どんな処理?
SystemHandler # システムを...ハンドル?意味不明
動詞 + 名詞 + Service:
CreateUserService # ユーザーを作成する!
SendEmailService # メールを送信する!
CalculatePriceService # 価格を計算する!
📐 命名のテンプレート
[動詞] + [名詞] + Service
↓ ↓ ↓
何を 何に対して サービスクラス
する? であることを示す
🔍 動詞の選び方
作成系:
-
Create- 新しく作る -
Generate- 生成する -
Build- 組み立てる
取得系:
-
Find- 探す -
Search- 検索する -
Fetch- 取得する
更新系:
-
Update- 更新する -
Modify- 変更する -
Refresh- 再読み込みする
削除系:
-
Delete- 削除する -
Remove- 除去する -
Destroy- 破棄する
処理系:
-
Process- 処理する -
Calculate- 計算する -
Convert- 変換する
送信系:
-
Send- 送る -
Deliver- 配達する -
Broadcast- 配信する
検証系:
-
Validate- 検証する -
Verify- 確認する -
Check- チェックする
❌ 避けるべき動詞
-
Handle- 曖昧すぎる -
Manage- 何をマネージするか不明 -
Process- 具体的でない(CalculateやConvertの方が良い) -
Do- 何をするか分からない
🎪 実際の命名例
ECサイトの例
class AddCartItemService # カートに商品を追加
class RemoveCartItemService # カートから商品を削除
class CalculateShippingFeeService # 送料を計算
class ApplyCouponService # クーポンを適用
class SendOrderConfirmationService # 注文確認メールを送信
ブログサイトの例
class CreatePostService # 記事を作成
class PublishPostService # 記事を公開
class SchedulePostService # 記事を予約投稿
class SearchPostService # 記事を検索
class GenerateSitemapService # サイトマップを生成
class OptimizeImageService # 画像を最適化
✅ 責務を見分けるコツ
❓ 質問してみよう
- 「このクラスは何をするクラス?」 を一言で説明できる?
- 「〜も〜も」 という説明になってない?
- 変更理由が複数ある? (メール変更、DB変更、UI変更など)
📝 名前をつけてみよう
-
良い名前:
CreateUserService,SendEmailService,CalculatePriceService -
悪い名前:
UserManager,DataProcessor,SystemHandler
「〜Manager」「〜Handler」「〜Processor」という名前は、責務が曖昧な証拠かも!
📋 チェックリスト:良い責務設計か確認しよう
- 動詞が明確で具体的?
- 名詞が対象を正確に表している?
- 一言で何をするか説明できる?
- 他の開発者が見ても分かりやすい?
- 「〜も〜も」という説明になってない?
- テストしやすい?
- 変更理由が1つ?
🎯 まとめ
責務 = その人(クラス)が担当する1つの仕事
「動詞 + 名詞 + Service」の命名規則で担当を明確にする
- 🧠 分かりやすい - 何をするかすぐ分かる
- 🛠️ 壊れにくい - 一部の問題が全体に影響しない
- 🧪 テストしやすい - 必要な準備が少ない
- 🔄 他でも使える - 再利用しやすい
Discussion