あたりを主戦場としておりますこの広告は、90日以上更新していないブログに表示しています。第2のドワンゴアドベントカレンダー、20日目の記事です。qiita.comドメイン駆動設計に関して悩める若者に送るポエムを書いていたら長くなりました。はじめればいいんですか?」と聞かれることがあります。この時にまず話に上がるのが、エンティティ、集約、レイヤードアーキテクチャといった設計パターンの内容が多いです。して認識している事が多くある様に思います。現実のプロダクトにより取り入れやすくなります。適用レベルという考え方について紹介します。実践思想であり、エリック本人の意図とずれている可能性もあります。ついて簡単に説明します。ひとことで言うと「ドメイン(問題解決領域)を中心に据えたソフトウェアの設計哲学、手法」です。なく、ドメインである、ということです。ドメインとはなんでしょうか。ドメインは、業務領域と表現されているものも多いですが、最近らしい言い方をすれば、「提供するプロダクトが扱う問題解決領域」のことを指します。すると、「提供するプロダクトが扱う問題解決領域を中心に据えたソフトウェアの設計哲学、手法」となるのですが、もう少し具体的に説明するとどの様な定義になるのか。以下4つの原則からなると説明しています。設計手法ではないという事です。根幹は、「現実の複雑な問題解決領域をどの様にソフトウェアに落としこむか」というテーマの、組織、開発プロセス、設計論に及ぶソフトウェア開発哲学であり、その探求の過程で生まれたモデリングの戦略、戦術のパターン、思想の集まりです。コンセプトを正しく理解し、実践、議論を深めるには、よくスポットがあたりがちなレイヤードアーキテクチャ、エンティティなどの設計手法、つまり戦術だけではない事、そして、言及の対象もソフトウェアそのものについてだけでなく、組織、開発プロセス論まで含む、ソフトウェア開発哲学であるという事をしっかりと認識する必要があります。ことを設計手法だけではない、ソフトウェア哲学でもあると表現しました。思想は大きく以下の様に分類できます。いう誤解もなくなります。関数指向プログラミングの登場により、エンティティなど一部パターンは変わりうると話しています。モデルで集約が表現できるとかそういった意味だと思います。理解し、自プロダクトにおけるドメインモデルの全体像を描いてから、はじめて「戦術」を検討すればよいのです。海外の動向を見ていると、エリックの哲学や戦略を引き継ぎながら、より発展した戦術の議論に進んでいる様に思います。捉えると、哲学、戦略面では、思想自体の汎用性は高くあらゆるプロダクトに取り入れる事はできます。仮に戦術を完全には採用せず隔離されたドメインモデルが構築されていなかったとしても、プロジェクトメンバー内で共通のメンタルモデルが構築されており、そのドメインにおける問題がソフトウェアによって解決できていればそれだけでも大きな意味があります。実践している」とは言えないでしょう。思想を取り入れる」という考え方でも十分に有用だと考えています。適用レベル」というコンセプトについて紹介します。してのドメイン駆動設計を取り入れるこのレベルでは、幾つかの戦略レベルの思想を取り入れ「ドメインの領域を定め、ユビキタス言語を構築する」までを実施するものです。大きく以下のパターンを利用してアーキテクチャを考慮します。コアドメイン、サブドメイン、汎用ドメイン境界づけられたコンテキストコンテキストマップユビキタス言語これはドメイン駆動設計というよりは、責務の境界線を意識した情報設計(IA)をしましょうというレベルの話です。毛色は全く異なりますが、こちらの様な本も参考になるかもしれません。見るここで重要なのはユビキタス言語は「用語集」ではないという事も言えます。言葉は他の言葉との関係性により、意味が決まります。その為、二次元的な用語集ではなく、それらの関係性が分かるダイアグラムもつくるのが望ましいです。レベル1は、「モデルとコードが一致していること」は重視せず、プロダクトのメンタルモデルの形成と、そのモデルによる一貫性あるユーザー体験の提供を重視し、語彙の統一はしつつも、ソフトウェアは問題解決のソリューションとしてのみ機能させるイメージです。ベースのドメイン駆動設計を取り入れるいわば守破離の守。レベル1に加え、大きく以下のパターンを取り入れます。原典だけでは具体性に欠け、コードに落とし込むにはかなりの試行錯誤が予想されます。実践ドメイン駆動設計など、コードレベルに落としこまれた書籍も参考にすると良いと思います。見るまたこのレベルの注意としては、コードと切り離せなくなる都合上、技術やフレームワークなどとの相性問題、そして実施する場合のコストがどうしても発生します。厳密な適用が必要なのかよく考える事も重要です。発展的なドメイン駆動設計を取り入れる守破離の破、離の段階です。ドメイン駆動設計の哲学、一部のコアとなる戦略、思想を引き継ぎ、関数指向のアプローチ、イベント指向のアプローチなど、新しい戦術を適用するレベルです。他のコンセプトとドメイン駆動を組み合わせる様な実践方法が多く登場しています。関数指向やアクターモデルを利用した実践例としては、以下の書籍が参考になります。戦略、戦術という明確な区分けの中での具体的な手法を知りたければこの書籍が参考になります。コードで利用される語彙も整えられてくるはずです。その上でプロダクトが複雑なドメインを扱う場合や、長期的に保守が予想され技術的な外的変化から中心となるコードを守りたい場合は、レベル2を検討しましょう。採用していない場合や、旧来のアーキテクチャで対応できないスケーラビリティを要求される場合など、より発展した活用が必要であればレベル3に挑戦しましょう。根幹は「現実の複雑な問題解決領域をどの様にソフトウェアに落としこむか、変化させていくか」という哲学であり、このテーマに取りかかったのならあなたも智を求める立派なドメイン駆動の哲学者です。実践だと捉えています。実践していく上での助けになれば幸いです。エントリに触発され、元文章の目的はさておき、技術的負債についての自分の考えを書いてみようと思う。技術的負債の定義や、問題は下記エントリを参照して頂くとして、なかでも最後の「技術者がすべきこと」について、「自分だったらこの様にアプローチするか」ということを書く。開発前にステークホルダー(ここではプロジェクトの責任者とする)に、プロジェクトの性質として何を重視するかを認識、選択してもらう。選択するという事について、健全でない状態や、成長速度が犠牲になった状態がどの様なものかを、プロジェクトが走り出す前に十分に認識してもらう必要がある。語れる様な綺麗な世界ではない。認識の元、動きだしたプロジェクトであっても、予測できない現象が発生したり、不完全な人によってコードが書かれる限り、負債というものはどうしても発生する。ステークホルダーはその事実を認識していないか、または理解してもらえない様な場合にどうすればいいのか。負債を明らかにする為に負債の総量を見積る元記事でも言及されている様に負債には様々な種類があり、モノにより定量化が困難な負債も存在する。不確実性の高い新規開発において時間ベースの見積りが意味を無さないのと同様に、大量の不可解なコード、存在しないドキュメント等の負債を抱えたプロダクトがチームに与える影響を絶対的な単位で定量化しようともまず無理だろう。等のポイントで負債の大きさを見積る。今目の前で曖昧になっている「技術的負債」というものを数値で明確化する。自分達が負債をどの程度抱えているのか、その負債が与えるインパクトがどれ程か、という感覚を定量化し、チームとして負債を認識する事が重要だと思う。数値の規模感を共有する為にストーリーにする負債を相対的に数値化したところで、既に共通認識が形成されているか、余程理解あるステークホルダーでない限り、「ひー、80ポイントもあるんだ。今すぐ返済しよう」とは言ってくれないだろう。最初に必要なのは、やはり技術的負債がどの様なものであり、それがステークホルダーにどの様な影響を与えるか、これを理解してもらいやすい単位でストーリーとして話せる様に整理する必要がある。ストーリーの粒度に関しては、開発内部の負債の整理は細かくやってもいいと思うが、対ステークホルダーの説明としてはかなりざっくり、スクラムでいうエピックレベルでいいのかなとは思うサービス開発におけるストーリーとは違い、すべてのストーリーに対して詳細に説明する必要はおそらくなく(おそらく負債について全部理解したいという動機がそもそもない)、幾つか内容として理解してもらいやすく、影響が大きいものをピックアップし、それらのストーリーに与えられたポイントの規模感さえ掴んでもらえれば、あとは負債のポイントの総量が明確であれば、「同様の問題がこれだけあるのか...」という風に想像がつきやすい。すると、理解あるステークホルダーであれば、ここで語られたストーリーの時点で、技術的負債の返済について具体的な計画を話し合える状態になる事もあるかもしれない。がでないと意味がない。ありそうなパターンとしてはプロジェクトチーム内ではその問題を共有できても、チーム内だけでは負債を返却するだけの期間をリソースを確保する権限がなく、上層部を説得する様な必要がある場合も容易に考えられる。その場合は、特定のインパクトある負債を抱えた状態のストーリーをプレゼンテーションするのは同様だが、自分達が見積ったポイントあたりのコストというのも算出し、提示することで、負債がどの様にコスト等のビジネスインパクトを与えるのかを、上層部も納得しやすい理由を作ることができればよいと思う。コストの算出に関しては、例えば現状のチームのおよそ人件費をベースに、いくつかの負債のストーリーを負債を抱えた状態と、返済した場合の人件費を比較してみて、ポイントあたりのコストを算出し、あとは負債の総量とかけあわせて、負債を抱えた状態で開発を続ける事がいかに経済的な合理性がない事を共有(多少でっちあげる事が)できればいい。共通認識にする上記に書いた様な事が共通認識として形成されれば、健全な体制を作るのは比較的容易で、負債のポイントあたりのイメージが形成できている為、開発過程で負債が発生しようが、定期的に技術的負債を見積る、共有するというマイルストーンを設けておけば、あとはサービスに要求されるスピードに応じた返済プランをプロジェクトチーム内で検討できればよいし、「負債のポイントが50ポイントに達したら新しい要求は受けつけられない。返却フェーズとする」という様な決まりでもいいだろう。それでもまた負債が無視され、スピードだけが求められる様なことがあったら、負債が及ぼす影響のストーリーと、数値化されたその時点での負債の総量を示し、再び負債を返却すう必要がある時期だという事を主張するプレゼンテーションの場が必要かもしれない。人と人が関わる開発においては、そもそも技術的負債という概念や、負債のポイントあたりの規模感などの共通認識の形成こそが重要で、一旦共通認識が形成されれば、コミュニケーションコストが減り、開発効率は上がり、健全なソフトウェア開発ができるのではないかなと思う。まとめ以上、技術者がすべきこと、として考えていることをまとめると、プロジェクトを開始する前に、何を優先し、何を犠牲にするか、ステークホルダーに十分に認識を共有する負債を定期的に観測し、ステークホルダーと共有できる単位で数値化し、ストーリーで語り、理解を得る技術的負債における影響と、ポイントあたりの規模感を共通認識とし、閾値などを設けて仕組み化するというあたりかなと考えている。捕捉こんな面倒なことせずとも、話して終わればそれでよい。チームで相対的なポイントにより負債の総量を常に把握するのはよいプラクティスだと思う。解のないチラシの裏です。セッションをどう引き回すか、というのが問題になる。等の特定の永続化層への依存が生まれるし、かといって永続化層に隠蔽するとアプリケーション層からの柔軟なトランザクション管理が出来なくなる。解決するパターンの記事を書いた。いうアンカファレンスでも話しにでた。DDDでリポジトリパターンを記述する際にConnection/Transactionをインフラ層で制御するが、ContextをImplicitで引き回すところは議論がある。