システム開発で思うところ

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

DDDでリファクタリング後を検討してみる

★この記事は過去の検討内容です

再検討のまとめ 

vermeer.hatenablog.jp

 

以下は過去の検討メモです。

振り返りができるように残します。

 現在、システムのリファクタリング中。

大きなシステムではないですし開発者も利用者も基本的に私一人です。

そんな中で、ああしたら良いかも、こうしたら良いかもと考えながらやっていたわけですが、闇雲にやるのは良くないなと。ということで、自分なりのゴールを一度整理しておいた方が良いだろうと思い、まとめてみました*1

 

なぜDDD?

システムの規模だけを考えたら無理をしてDDDじゃなくても問題はない気がしています。ただ、今後も拡張・メンテナンスをするシステムなのでDDDを取り入れるのが良さそうだと考え至りました。*2

 

どのように検討した?

先人の知恵を参考にしつつ、過去の経験を踏まえて分類・整理しました。

参考にさせていただいた知恵

 

全体図

前提・共通事項

レイヤー

要素

View

Domain

Infrastructure(Service)

Infrastructure(Common)

補足

 

[改訂版] UMLモデリング技能認定試験<入門レベル(L1)>問題集 -UML2.0対応

[改訂版] UMLモデリング技能認定試験<入門レベル(L1)>問題集 -UML2.0対応

 

 

エリック・エヴァンスのドメイン駆動設計

エリック・エヴァンスのドメイン駆動設計

 

 

実践ドメイン駆動設計

実践ドメイン駆動設計

 

 

検討メモ

2016/12/26:Ruleはstaticではなくクラスで(∵DI対象に拡張できるように)

 

2017/8/8:RepositoryはServiceではなくInfrastructure。

基盤=インフラという整理でビジネスに近いということでServiceと考えていたけれど調べてみると、Service(Domain)ではInterfaceを定義しておいて、Infrastructureで実装するということだった。こうしておくことでJPA依存からDomainを守ることが出来るという考え。

逆に基盤=インフラという整理の部分はレイヤーはInfrastructureで良いけれど、Commonとして別パッケージにしておいた方が、個人的にはシックリくるという整理にも至った。

 

 2017/8/10:トランザクションの境界はService

DDDにおいて、なぜ複数の集約にまたがってトランザクションをかけてはいけないのか(multiple aggregates in one transaction) - pospomeのプログラミング日記

(整理資料の更新は未実施)

・データの整合性を保つのが誰の役割なのかに注目する
・それがユーザー自身であれば、トランザクション整合性を保つようにすればいい
・それが別のユーザーであれば、結果整合性を保つようにすればいい 

 

 2017/9/2:

Repositoryは「コト」を経由して Aggregate(集約)のルートを返却すると良い?

つまりRepositoryクラスは「コトを表すEntity」または、概念(クラスが無いケースや外部サービス)で作ると良い?

もし集約ルートクラス単位でRepositoryを作成したらルート配下に何が存在するのか「知っている」ことになる(もしくは「知っていないといけない」)。そしてRepositoryのメソッドが大変多くなってしまう。

この仮説が正しいとしたら、これまで自分が作成していたRepository(というかDAO)の発想から変えたほうが良くなる。個人的には「コトをRepositoryにする」というのは良さそうな気がするので、実装実験をするときには1つの指針としてみよう。

 

2017/9/2:validation は service を経由しない検証ルール(とする)

 

2017/9/2:副作用のある操作には Assertions(表明)パターン「契約による設計」

操作の結果として何が保証されるかという事後条件(post-condition)と、操作の前後で変わらないものは何かという不変項(invariant)とを、明示的に示す。

ということらしい。ということは更新操作をするRepositoryには事後検証を必ずすべきということかな?性能面が心配だけど結果整合性を保証するという意味では正しい。

でも、これまで実装していて、こういう事後検証はしたことが無かったなぁ。やっていないから良いという訳ではなくて、本来はするべきだったんだろうなぁという気づき。

でも「単体テストで保証できる」ともあるから、これは実行時の話ではなくて実装時の話なのかな?んー良く分からない。

 

2017/9/2:Closures of Operations

値オブジェクトにおける計算の結果は同じ型の値オブジェクトの返却で表現をするべき?「計算の結果(例えば数値のようなプリミティブな型)」を返却せず、「計算」と「値の取得」の2段階にするべき?

 

2017/9/7:データ中心思考とオブジェクト指向の違い

データ中心指向とオブジェクト指向

 

 2018/2/23:レイヤードアーキテクチャの参考

中規模Web開発のためのMVC分割とレイヤアーキテクチャ - Qiita

 

2018/2/28:レイヤー構造の参考に

ウェブアプリケーションの構造について - じゅんいち☆かとうの技術日誌

 

2018/3/1:

外部設定関係は独立したパッケージ(プロジェクト)にした方が良いかも
インフラ層で発行したメッセージ(例外詳細)をドメイン層で扱うことを考えていた際に思ったところ。
インフラで発行した情報を変換なり利用なりしようとすると、その方が良いように思う。
実装面で考えたら、インフラ層で発生した情報の管理主体はインフラ層のプロジェクト配下になるけれど、そうしてしまうとドメイン層からは扱い辛い気がする。
Repository同様、インターフェース経由で、というのも考えどころではあるけれど、情報詳細に応じたハンドリングをする類のものだと考えるので、それも悩ましい。
例外という独立したドメインに対して要件を整理する、ということに注力するのであれば「独立したパッケージ(プロジェクト)」にするという構成が悩みが少ないかもしれない。
分割過剰な気もするので、実装含めて、ちゃんと検討が必要。

 

2018/3/14:ValueObjectの参考に

マニュアル: ドメイン駆動設計: Value Object - Hideki Ikemoto's Site

https://projectlombok.org/features/Value

*1:スライド貼り付けなので、若干やっつけ感がありますが・・・

*2:とはいえ、DDDについてですが、きちんと分かっていないと思います。有名どころの書籍も読んだことはありません。UMLもかなり昔に勉強したなぁ、という感じです。