社内でオブジェクト指向ワークショップを開催

先日、社内でオブジェクト指向ワークショップを開催しました。

せっかくなので、公開します。

目的

オブジェクト指向の基礎的な考え方を身に付けてもらうことです。

また、実際のプロジェクトのコードだと、なかなかチャレンジしにくいオブジェクト指向の考え方に振り切って、設計・実装してみる。というのを体験してもらう機会を作りたかったからです。

オブジェクト指向の考え方のわかりやすい実践例として、オブジェクト指向エクササイズかなっと思います。

オブジェクト指向エクササイズの全手段を、こういうワークショップで経験してもらうことにより、何らかの気づきがあると思い、その気づきを実際のプロジェクトで反映してもらえたら、うれしい限りです。

環境

・言語 : Java8

・ビルドツール : Gradle

プラグイン : Lombok

準備

コードのclone

ワークショップで使うコードは、以下のGitHubからcloneしてください。

mmm-mao/object-oriented-workshop · GitHub

テスト実行

プロジェクト直下に移動して、以下コマンドを実行。

 ・./gradlew clean test

 ※windowsの場合は、./gradlew.bat clean test で動くと思います。

コマンド実行して、「BUILD SUCCESSFUL」が表示されたら、大丈夫です。

資料

www.slideshare.net

時間があれば、ワークショップやってみて、感想など教えてもらえたらと思います。

以上です。

ドメイン駆動設計の捉え方のスライドを作成

www.slideshare.net

DDD本を読み終えたので、まとめのスライドを作成しました。

本を読んで良かった点や実践で感じている点を反映させた内容になっていて、今回は、「DDDの捉え方」編という位置付けでまとめたので、あまり実践ネタはないです。すいません。。。

また、おそらく半年も経てば考え方が変わると思ったので、「2015/07/18版」という感じにしています。

これからDDDやる人や既にDDDやっていて悩んでいるような人にとって、いい刺激になればと思っています。

あと、どこかのタイミングで、実践編もスライドにまとめれたらと思っています。

P.S. 今回のスライドをどこかの勉強会で喋ってみたいが、喋る機会はあるのだろうか。。。

まぁ、いつでも喋れるように準備だけはしておこう!

エリックエバンスのドメイン駆動設計の「第17章 戦略をまとめ上げる」まとめ

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

今回は、「第17章 戦略をまとめ上げる」のまとめです。

戦略的設計上の意思決定を行うための6つのこと

意思決定はチーム全体に伝える

  • 全員が戦略を理解して、行動しないと意味がない。

  • アーキテクトチームよりアプリケーションチームから現れる戦略的設計が全員に伝わりやすいので、より効果的かもしれない。

意思決定プロセスはフィードバックループが必要

  • アーキテクトチームが戦略的設計を考える際は、実際に手を動かしてフィードバックを得ることが重要。そうしないと、非実用的な設計になってしまい、アプリケーションチームが設計を無視する可能性がある。

  • アーキテクトチームとアプリケーションチームの両方が協力して、戦略的設計を考えることができれば、ベスト。

計画は進化を許容する

  • 開発プロジェクトの進行に合わせて、戦略的設計も成長させる。そうしないと、逆に戦略的設計が開発プロジェクトの進行の妨げになってしまう。

アーキテクチャチームが、最も優秀な人材を全て吸い上げてはならない

  • 優れたアプリケーションを構築するためには設計スキルが必要だから、アプリケーションチームに強力な設計者を入れることが不可欠。

戦略的設計にはミニマリズムと謙虚さが必要

  • いつ、プロジェクトにとって障害物となる戦略的設計を導入するかわからないので、 設計を特に明確にするものだけ・余分なものを削ぎ落とさせた考えだけを適用。

  • 自分にとって最高の考えでも、誰かの妨げになるかもしれないと認識するためには、謙虚さが必要。

オブジェクトはスベシャリストだが、開発者はジェネラリストである

  • うまくいっているプロジェクトには、開発者がフレームワークを試し、アーキテクトがアプリケーションコードを書き、担当領域外の仕事も実施。

以上が「第17章 戦略をまとめ上げる」のまとめです。

エリックエバンスのドメイン駆動設計の「第16章 大規模な構造」まとめ

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

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

今回は、「第16章 大規模な構造」のまとめです。

概要

巨大なシステムに包括的な原則がなく、各要素を解釈する際に、設計全体にまたがるパターンにおいてどのような役割を果たすかという観点から考えることができなければ、開発者は「木をみて森を見ず」になってしまいます。

そのため、全体の詳細を徹底的に調べなくても、全体の中で個々の部分が果たす役割を理解できる必要があります。

「大規模な構造」は、システムをおおよその構造から議論し、理解できるようにするための枠組みです。

大規模な構造を使用するという選択は、個別の部分を最適に構造化するよりも、モデル全体としての扱いやすさを優先するということです。

また、大規模な構造を適用すべきなのは、モデルの開発に不自然な制約を強いることなく、システムを大幅に明確化する構造が見つけられた時だけです。

進化する秩序

設計に制約がなければ、出来上がるシステムの全体像が誰にも理解できない上に、保守するのも非常に困難になります。

ただし、設計上の意思決定の融通が利かないアーキテクチャは、要件が変化し、ドメインに対する理解が深まるにつれ、開発者を束縛することになります。

そのため、ドメインに関する実際の経験と知識に基づいて構造を選択し、過度に制約的な構造を避けることが重要です。

責務のレイヤ

ドメインモデル内にある概念上の依存関係を調べて、自然な階層が認められたら、階層に抽象的な責務を割り当てを実施します。

階層は、ドメインの基本的な現実や優先事項を伝える必要があります。

また、階層の責務を決める際は、技術的な意思決定というより、ビジネス上の意思決定で行います。

具体的なイメージは、本書から以下を抜粋します。 f:id:mmm-mao:20150715090321j:plain

本書に紹介されている抽象的な責務は以下の通りです。 f:id:mmm-mao:20150715091347j:plain

知識レベル

他のオブジェクトグループがどう振る舞うべきかを記述するオブジェクトであります。

例えば、従業員タイプや会員タイプなどが知識レベルで、従業員や会員が業務レベルの内容になります。

僕は普段Javaで開発しているんですが、enumを利用するケースは、知識レベルの内容になると思います。

f:id:mmm-mao:20150715092305j:plain

まとめ

f:id:mmm-mao:20150715083840j:plain

以上が「第16章 大規模な構造」のまとめです。

エリックエバンスのドメイン駆動設計の「第15章 蒸留」まとめ

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

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

今回は、「第15章 蒸留」のまとめです。

概要

蒸留とは?

混ざり合ったコンポーネントを分離するプロセスであり、価値があって役立つ形式で本質を抽出することです。

蒸留する動機は、システム内で最大の価値を付加すべき場所、すなわち「コアドメイン」を抽出したいという欲求になります。

ドメインモデルに対する戦略的蒸留

ドメインモデルに対する戦略的蒸留は、以下に挙げる全てを行います。

  1. システムの全体的な設計と、設計同士がどう関係するのかを、チームメンバ全員が把握できるようにする。

  2. ユビキタス言語に入れやすいサイズのコアドメインを識別することで、コミュニケーションを促進する。

  3. リファクタリングの指針となる。

  4. モデルで最も価値がある領域に作業を集中する。

  5. アウトソーシングと既製のコンポーネントの利用、その割り当てについて、決定する際の指針となる。

今回は、コアドメインの戦略的蒸留に対する体系的なアプローチを提示します。

f:id:mmm-mao:20150708115705j:plain

コアドメイン

コアドメインで実現したいことは、以下が挙げられます。

  • コアドメインを見つけて、コアドメインをサポートする大量のモデルやコードから容易に区別する手段を提供すること。

  • 最も価値のある特化した概念を浮き彫りにすること。

  • コアは小さくすること。

コアドメインを蒸留していくことにより、設計の意思決定が容易になっていきます。

汎用サブドメイン

ドメインモデルの中には、専門的な知識を捉えることも伝えることもなく、複雑さを付け加えるだけの要素があります。

本質と無関係なものがあると、それが何であれ、コアドメインを見分け、理解するのが困難になります。

ただ、本質とは別の要素とは言え、システムを機能させ、ドメインモデルを完全に表現する上で欠かせない要素です。

このような要素を汎用サブドメインとして識別して、別のモジュールに入れることを実施します。

汎用サブドメインに対しては、既製品(OSSなど)による解決策や公表されているモデルの採用も検討します。

ドメインビジョン声明文

最小の投資で基本的な概念とその価値を伝えることを目的として、ドメインビジョン声明文は開発チームを共通の方向に向かわせ、モデルとコード自体の蒸留を続けさせます。

ドメインビジョン声明文の具体的な内容としては、以下が挙げられます。

  • コアドメインとそれがもたらす価値に関する簡潔な記述を作成すること。

*ドメインモデルを他と差別化するものでない側面は無視すること。

  • ドメインモデルがどのように役立ち、多様な関心に対してどうバランスを取るかを示すこと。

強調されたコア

コアドメインを全員が理解しやすくするテクニックが必要で、蒸留ドキュメントやドメインモデルにコアドメインを印付けするなどがあります。

ただ、強調することが目標なので、これにより設計を変更する必要はありません。

凝集されたメカニズム

アルゴリズムなどの概念的に凝集された部分を切り分けて、別のフレームワークとして括り出し、意図の明白なインターフェースを用いて、フレームワークの機能を他から使えるようにします。

これにより、ドメインの他の要素は問題を表現することに集中でき、複雑な解決手段はフレームワークに委譲できるようになります。

汎用サブドメインと凝集されたメカニズムはどちらもコアドメインの負担を軽減する観点であるが、それぞれ引き受ける責務が違います。

それぞれの責務は以下の通りです。

隔離されたコア

パッケージし直すことで、コードの中であっても、コアドメインが直接見えるようになり、コアドメインに対する将来の作業が容易になります。

抽象化されたコア

サブドメインに分割していくことにより、各種モジュールもいずれかのサブドメインに移動します。

場合によっては、サブドメイン間でモジュールの依存関係があると、かえって複雑になり、分割した価値がなくなってしまいます。

そのため、モジュールの概念を考えて、それを別クラスやインターフェースに括り出します。

抽象化されたコアの導入前 f:id:mmm-mao:20150708153034j:plain

抽象化されたコアの導入後 f:id:mmm-mao:20150708153044j:plain

以上が「第15章 蒸留」のまとめです。

エリックエバンスのドメイン駆動設計の「第14章 モデルの整合性を維持する」まとめ

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

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

今回は、「第14章 モデルの整合性を維持する」のまとめです。

概要

ドメインモデルに対する最も根本的な要件は、用語の意味が常に同じであることであり、矛盾したルールが含まれていないことです。

エンタープライズシステム全体のドメインモデルに対する根本的な要件を満たすことは、現実的ではないし、コストにも見合わないと考えられます。

ただ、現実的ではなくても、何を統一すべきか/何を統一しないでおくべきかを意思決定して、置かれている状況に関する全体像を共有できるようにします。

この全体像があれば、確実に統一したい部分を統一する方向に向けつつ、統一しない部分のせいで混乱や破綻が生じないようにできます。

この章で説明することは、ドメインモデルの境界や他ドメインモデルとの関係性を認識し、伝達し、選択するためのテクニックです。

まず、境界づけられたコンテキストによって、各ドメインモデルを適用できる範囲が定義され、コンテキストマップによって、プロジェクトのコンテキストと、それらコンテキスト間の関係性を全体的に見渡せることができます。

次に、継続的な統合のプロセスによってモデルの統一性が保たれます。

最後に、これらが安定することによってコンテキスト同士を関係づけるためのより効果的な戦略へと移行できます。

境界づけられたコンテキスト

複数ドメインモデルに基づくコードが組み合わされると、バグの温床となり信頼できなくなり、理解しにくくなり、最後にチームメンバ間のコミュニケーションは混乱し始めます。

そのため、ドメインモデルが適用されるコンテキストを定義する必要があります。

コンテキストの境界は、

  • チーム編成

  • アプリケーションが持つ用途

  • コードやデータベースなどの物理的な表現

などの観点から設定します。

その境界内では、モデルを厳密に一貫性のあるものに保つことが重要です。

明示的な境界を用いることで、チームメンバは一貫性を保つべき部分が把握でき、それを他のコンテキストとどう関係づけるかを、明確な理解を共有できるようになります。

継続的な統合

境界内で行われるすべての作業について、頻繁に統合して一貫性を保つことにより、考え方の分裂が見られた時にすぐに発見して修正できるようになります。

継続的な統合も、他のDDDパターンと同様に、以下2つのレベルで作用します。

No レベル 内容
1 ドメインモデルの統合 チームメンバ間の絶え間ないコミュニケーションによって実現され、日々変化するモデルに関して、共有された理解を培う。最も基本的な所として、ユビキタス言語を統合させる。
2 実装の統合 頻繁に、各開発者のコードをマージする。

コンテキストマップ

それぞれの境界づけられたコンテキストに対して明確な名前を与えた上で、ドメインモデル同士の接点を記述して、あらゆるコミュニケーションで必要となる明示的な変換の概略を述べます。

以上が「第14章 モデルの整合性を維持する」のまとめです。 本来なら、「境界づけられたコンテキスト間の関係」があるんですが、種類が多すぎたので、まとめは省略しました。

エリックエバンスのドメイン駆動設計の「第4部 戦略的設計」まとめ

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

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

今回は、「第4部 戦略的設計」のまとめです。

たった2ページですが、すごい重要そうな臭いがプンプンしますね。

大規模エンタープライズの課題

大規模エンタープライズの課題として、以下2点が挙げられます。

  • あらゆるものを含む一枚岩のドメインモデルは大きすぎて扱いにくく、微妙な重複と矛盾が詰め込まれる。

  • 別々の小さなサブシステムの統合がその場しのぎのインタフェースでつなぎ合わされていたら、エンタープライズ全体の問題を解決する力は失われる。また、統合のあらゆるポイントにおいて、一貫性に関わる問題が発生する。

進化する体系的な設計戦略によって、課題を解決できます。

戦略的設計の原則

設計上の意思決定を導いて、各システムの相互依存関係を減らし、設計をより明確にしながら、重要な相互運用性と相乗効果を得る必要があります。

また、システムの概念的にコアを捉えるモデルに集中します。

戦略的設計の具体的なアプローチ

戦略的設計の具体的なアプローチとして、

  • コンテキスト

  • 蒸留

  • 大規模な構造

があります。

コンテキスト

明示的に境界づけられたコンテキストを定義した上で、モデルを適用するのはコンテキスト内部に限定します。 さらに、必要に応じてコンテキスト同士の関係も定義することによって、モデルの質が低下するのを避けます。

蒸留

注意の対象をコアとなる場所に絞り、他の要素を脇役として示せるようになります。

大規模な構造

全く異なるものから構成される部分に一貫性をもたらして、それらの部分を調和させる上での助けになります。

まとめ

「大規模な構造」と「蒸留」によって、各システム間にある複雑な関係を理解できるようになる一方で、全体像を見失わずにいられます。

境界づけられたコンテキストによって、別々のシステムの作業を進めても、モデルを壊してしまったり、意図せず断片化してしまったりすることがなくなります。

以上が「第4部 戦略的設計」のまとめです。 具体的な話は、この次からになります。