概要
DDD は設計手法なので実装するとなるとまた話は別ですが実際に作ってみないとイメージが全くわかないので超簡単なサンプルを作ってみました
環境
- macOS 11.2.3
- Ruby 3.0.0
登場人物
- リポジトリ ・・・ DB の扱うレイヤ、DB の処理はここだけしか行えない
- エンティティ ・・・ 属性の管理を行うモデル、DB からデータ取得、追加など DB への操作はこのモデルのクラスのオブジェクトを渡すことで行う
- ドメインサービス ・・・ モデルとなるクラスのオブジェクトのユーティリティクラス、今回は重複チェックをしてもらう
- メイン ・・・ エンティティとドメインサービスを使ってメインの関数などを提供するクラス
とりあえずこんな感じで実装してみます
リポジトリ
- vim user_repository.rb
# coding: utf-8
# DB に関する処理をまとめて書く
# ここで ActiveRecord などを使う
class UserRepository
@@user_repo = {
"hawk" => 10,
"snowlog" => 20
}
def search_age(user)
@@user_repo[user.name.value]
end
def save(user)
@@user_repo.store(user.name.value, user.age.value)
end
def all
@@user_repo
end
end
エンティティ
- vim user_entity.rb
# coding: utf-8
# User の属性を管理する
# UserName, UserAge は immutable
class UserName
def initialize(value)
@value = value
end
attr_reader :value
end
class UserAge
def initialize(value)
@value = value
end
attr_reader :value
end
class User
def initialize(name, age)
@name = name
@age = age
end
attr_accessor :name, :age
end
ドメインサービス
- vim user_service.rb
# coding: utf-8
# User に関するユーティリティ機能を提供する
# UserRepositry を扱うことができる
require './user_repository.rb'
class UserService
def initialize(user)
@user = user
end
def duplicate?
ur = UserRepository.new
return false if ur.search_age(@user).nil?
return true
end
end
メイン
- vim main.rb
# coding: utf-8
# メインの処理を書くクラス
# UserEntiry と UserService を使って実装する
require './user_repository.rb'
require './user_service.rb'
require './user_entity.rb'
class Main
def create_user(val_name, val_age)
name = UserName.new(val_name)
age = UserAge.new(val_age)
user = User.new(name, age)
us = UserService.new(user)
return if us.duplicate?
ur = UserRepository.new
ur.save(user)
p ur.all
end
end
main = Main.new
main.create_user("hawksnowlog", 30)
ポイント
何をドメインとして切り出すかがポイントかなと思います
今回で言えば User がそれに当たります
User の属性を管理する「エンティティ」、User のデータ永続化を管理する「リポジトリ」、User の重複チェックなどを行う「ドメインサービス」と言った具合に User を主体に様々なクラスを作成しています
あくまでも一例ですが、こんな感じでドメインとして扱うオブジェクトというかモデルを抽出してそれを主体にコーディングしていく感じになります
また各ドメイン間での結合度を下げてることも重要で DI や引数などを使ってドメイン間やクラス間での依存性を下げる意識を持ったほうが良いかなと思います
(例えばサンプルだと UserService はメンバーである必要はないので引数にするとか)
最後に
DDD は設計手法なのでプロダクトの製品や使われているフレームワークなどにも大きく影響するものかなと思っているので一概に実装の正解はないかなと思っています
あと簡単すぎるので自分で書いていますが実践的ではないあまり良いサンプルではないかと思うので実際はもっと複雑になるかなと思います
0 件のコメント:
コメントを投稿