CureApp では DDD と JavaScript を使って小さなチームで柔軟にマルチプラットフォーム対応を実現しています。ここではそのために実施している方法や必要となる知識を共有します。
ちなみに実際に対応しているプラットフォームは次になります。
- Web
- desktop
- iOS
- Android
DDD という考え方
DDD とは Domain Driven Design の略で、 Eric Evans がソフトウェア開発を実践する中で得た知識・方法論をまとめて提唱したものです。日本語訳された本が出版されています。
以下これを DDD 本と呼びます。
ドメイン
ひとことでいうと「解決したい問題」のことです。ある疾患を治療したいという問題や、もっと簡単に飲料缶を自動販売したいといった問題、つまり自動販売機をどう実現するかなどがあたります。
モデリング
「解決すべき問題から見た物事の捉え方」ということになります。モノのモデリング例としてはオブジェクト指向の説明でよくあげられる、生物・哺乳類・人間などをどう表すかといったことになります。概念もモデリング可能で、たとえば自動販売機では「あたり」のあるものがありますが、これも具体的にどういうことが「あたり」なのかを定義していくことになります。
レイヤー化アーキテクチャー
実際に動くシステムを作るにあたり、層をわけ、各層に責務をもたせようという発想です。その他の分野ではネットワーク通信における OSI 参照モデルが有名です。説明は Wikipedia 英語版が詳しいです。
上記の図では 3 層ですが、 DDD 本では下から順にインフラ層、ドメイン層、アプリケーション層、ユーザーインターフェイス層とわかれています。 Logic tier がドメイン層とアプリケーション層にわかれた形ですね。
DDD 本ではドメイン層をいかに磨き上げるか、ということが多く記述されています。
DDD 本の読み方
ここでは説明の都合上、必要な概念だけを取り上げましたが、 DDD 本にはもっと重要で本質的なことがたくさん書かれています。個人的には設計者・開発者としての畑を耕す上でぜひ読むべき本だと思っています。
が、もともとが複雑な概念の説明ということ、翻訳するとニュアンスが失われやすいこと、とにかく厚い本であることなどから挑んではみたものの挫折したというハナシも聞きます。ここではそんな方のためにいくぶんか読みやすい方法を提案します。
第 1 部が DDD がどういった概念なのか、大切にしていることはなんなのかの説明、第 2 部が DDD を実践するために必要な考え方の紹介なので必須です。が、主張がとても整理されていることと技術的な要素は曖昧な点がないことから、迷わずに読めると思います。新しい概念が多いのでかみ砕きながらだと時間はかかると思いますが、設計・開発する上で役立つ知識なので踏ん張りどころです。
第 3 部から本質的な話題が並んでいますが、わりと昔に書かれた本なのでいくつかのトピックについては他の本を参照したりググったほうがわかりやすいことがあります。最低限読むべき章は次になります。
- 第 8 章 ブレイクスルー
- 第 9 章 暗黙的な概念を明示的にする
- 第 13 章 より深い洞察へ向かうリファクタリング
その他については次の書籍を読んだり、ググッて調べたあとでパラパラと主張を読んでいけば大丈夫です。
第 4 部は大規模開発においてどう DDD を役立てるかという話題ですが、システムは意図的に大規模化するとは限らないため、次の章だけはあらかじめ読んでおき、大規模化の兆候があったら対応できるようにしておく必要があると思います。
- 第 15 章 蒸留
- 第 16 章 大規模な構造
その他に関してはどういったことに触れているのかだけ覚えておいて、必要なときに読み返すということで十分なのではないかなと思います。
みんなで学習する
正直に告白すると、たぶんぼく一人では DDD 本を読み進めること、理解することは難しかったと思います。読書会に参加することで読む時間を確保でき、わからないことや複雑なことについて議論する場をもらえたことが非常に助かりました。
残念ながら上の読書会では読み終わってしまったのですが、もし興味のある方はイベント企画などすると良いかもしれません。勘所がわからない場合は呼んでいただければ駆けつけます。
また、議論・実践の場を設けられている勉強会もあります。こちらは実際に業務で使われている方々による主催ということもあって、ひとりだけの実践では掴みづらい感覚を教えていただけたことが役立ちました。
実践形式としてはこちらもあります。参加対象が実践者なので少し敷居が高いのですが、日本において第一線で DDD を実践されている方々と議論できる場なので得られるものが非常に大きいと思います。
JavaScript の普遍性
閑話休題。
現在 JavaScript で開発できるプラットフォームは実に様々です。各ブラウザーをはじめ、 サーバー、モバイルアプリなどでも問題なく動きますし、最近は IoT 用のチップで JavaScript を解するものも発売されています。
ということはつまり、一回ドメイン層を JavaScript で書いてしまえばどのプラットフォームでもその知識を使えるようになるということです。ただし、ドメイン層の各ロジックがどこでも動くことを保証できていれば、という前提が付きます。そこで必要となってくるのが universal JavaScript という考え方です。
universal JavaScript という考え方
Michael Jackson が 2015 年 9 月に提唱した概念で、ひとことでまとめると「どこでも動くようなコードを書こう」ということです。
どこでも動かせるようにするにあたっては、言語仕様のほかに各実行系がどのていど仕様に準拠しているかという情報が必要になります。
-
https://www.ecma-international.org/publications/standards/Ecma-262.htm
- EcmaScript の言語仕様
-
http://caniuse.com/
- 各ブラウザーでどの機能が使えるかがわかるサイト
-
http://node.green/
- Node.js でどの機能が使えるかがわかるサイト
また、近い将来どういった仕様が標準化されるかは非常に重要です。そのためにどこでどのように言語仕様が標準化されるかということは知っておいて損はありません。日本語でそのあたりを解説した資料としては次が詳しいです。
くみあわせるとつよい
ドメイン層を普遍的な JavaScript で記述することでマルチプラットフォームへ対応しやすくなります。残りは各プラットフォームにあわせた UI を作りこむことですが、こちらは昨今のフロントエンドに関する話題となります。
各プラットフォームにはそれぞれ固有の知識・スキルが必要となりますがドメイン層はどこを担当するにしても共通で必要となります。それをプラットフォームを記述する言語と同じものにあわせることで実行時の相互運用性を担保できるだけでなく、異なるプラットフォームを担当しているメンバー間でもドメイン層については同様の議論ができることを担保できます。
といったようにアプローチはとても理にかなっていますが、次にあげるような例外があります。
- 速度重視
- 数 msec 以下の精度で速度が必要な場合は残念ながら向いていません。パフォーマンスが求められる場合は C++ など速度重視の技術を採用したほうがよいと思います。
- ドメインを定義しづらい場合
- 自動販売機や特定の疾患など、問題とすべき範囲が明確に切り分けられる場合、 DDD は理想の方法論ですが、定まりきらない場合はまずユーザーインタビューやプロトタイプ作成などを通じてドメインをしっかりと定義する必要があります。
まとめ
同じ話題で過去に発表したことがあります。その際の資料をあわせてみていただくと理解が進むかと思います。
- https://speakerdeck.com/shinout/universal-js#14
- https://speakerdeck.com/januswel/marutipuratutohuomushi-dai-false-javascript-x-react-zhan-lue
明日は @imoans さんの iOS 10 の仕様変更のはなしです。