前回に引き続き、ChatWork株式会社のテックリードでいらっしゃいます加藤潤一さんのインタビューです。
エンジニアリングにもコミュニケーションは重要
愛宕 さて、これからは加藤さんの話や、DDDの実際的なところをお聞きしていきたいと思います。これまでもドメインエキスパートとコミュニケーションをとってきたと思いますが、そのご経験をお聞きしたいです。
加藤 今のチャットワークはドメインがある程度出来上がっていたので、それほど苦労はしませんでしたけれども、過去の職場では企画者の持ってきた提案が技術的には実装できないようなものがありました。こういう事例は分析の段階で弾かれるはずすが、分析を完全に終わらせてから設計をするようなプロセスだと手戻りが大きくなりやすいかもしれません。そのようなケースでは日々のコミュニケーションの中で、モデルに対して違和感が生じた際に、継続的にモデルに対してリファクタリングすることを意識した方がよいと思います。
愛宕 開発側としてやりやすいドメインエキスパート像のようなものはありますか?
加藤 これはSIer時代の経験ですけども、ドメインエキスパートの考えるドメインモデルが完璧だとする場合は、開発者側から提案しにくいですね。そういう場合はやりにくいです。金融とか保険などの、ある程度歴史がある、確立したドメインであればそういうこともありえると思います。しかし、ソフトウェア開発では、開発者の分析・設計も不可欠です。相互に信頼された共同体としてコミュニケーションを維持していき、ドメインに対して、組織として関心を持ちながら関わっていくことが重要ですね。一方、コンシューマ向けウェブサービスではどうかというと、顧客といってもそう簡単に会ってヒアリングできないので、ペルソナを作ったりチームに疑似ユーザが必要になると思います。SI案件のようにドメインエキスパートとしての顧客が存在する場合は議論しやすいですが、コンシューマ向けウェブサービスの場合はこのような代替手段があったとしても、知識をかみ砕いていくことは難しいと思います。
先ほども少し触れましたが、ドメインを取り巻く環境は利害関係者で構成される組織に大きく関係します。ある組織が社内外を含めて他の組織との関係を持っているかもしれません。先ほども説明したBCは、組織が解決しようとしている問題に強く関係します。つまり、ドメイン – BC – 組織 それぞれは強い関係にあります。そのBC内で、利害関係者がユビキタス言語を使ってモデルの概念を表現するので、そこから生み出されるアーキテクチャも組織構造に影響を与えます。また、アーキテクチャから組織を考えたり、またその逆で組織に合わせたアーキテクチャも考えることができます。いずれにしても、この相互作用の関係性を無視することは、組織やアーキテクチャにとってよくありません。
技術的な視点でアーキテクチャを考えていたエンジニアが、利害関係者や組織のことにも目を向けていかないといけないという話なので、いわゆるコミュ障だとツラいというのはあるかもしれませんね(笑)。
“俺はエンジニアなんで組織とは無縁”なんてなかなか言いがたいわけですから。僕も機械相手に仕事した方が楽だと思っていた口なので、DDDを知った時は正直 面くらいましたね…。いずれにしても、これまでの分析・設計・実装などに関する技術は無駄せずに、コミュニケーションの問題という新しく考える軸ができたのはよかったです。
DDDを適用できるのはオブジェクト指向言語だけか
愛宕 他社でも技術顧問もやられていると思いますが、どういったことをやっているのでしょうか?
加藤 当然、本業に影響しない範囲でやっていますが、DDDの目線でコードレビューや中途で入ってきた人向けの講座を不定期でやっています。社外の方々と具体的に議論することで新たな発見をすることがあります。いろいろな方とのつながりもできて、コミュニティを作って車座になって座談会イベントも開催したりしています。
愛宕 書籍に書いていることと、実際にやってみることは全然違いますよね…。
加藤 実際 議論になったのが、「Haskellのような純粋関数型言語でオブジェクト思考ができるか」とか、「C言語を使って手続きベースでDDDができるか」という話です。
書籍では、エリックさんはC言語では十分に実践することができないと言及しています。ステップ指向ではそもそもコードが伝える概念を表現しきれないと。それは同意です。しかし、言語の問題かプログラミングスタイルの問題かは切り分けた方がよいと思っています。僕はプログラミングスタイルの問題の方が大きいのではないかと思っています。なので、僕はプログラミングスタイルを重視する派です。たとえば、Javaなどのオブジェクト指向言語でもすべてをstaticメソッドで記述するようなスタイルだと、結局C言語の手続き型での状況と変わらなくなります。逆にC言語であっても関数の第一引数のレシーバに対する操作として関数を記述するスタイルでは、オブジェクト指向のメンタリティに近くなっていきます。概念を表すために必ずしもクラスが必須ではないかもしれません。そういう意味からすると、HaskellやGo言語でも分析・設計・実装を反映した単一のドメインモデルは実装できると思います。
1つだけ落とし穴があるとしたら、その言語の設計思想・コミュニティ・チームの文化に逆らって、そのようなスタイルを強いることは好ましくないでしょう。たとえば、オブジェクト指向スタイルで記述されたCコードは、アップキャスト時にキャストがあちこちに必要なので可読性が低下したりします。できることと役に立つことは、意味が異なります。こういう意思決定は慎重に考えた方がいいでしょう。
DDDを太古の古典だと揶揄する人もいるほどです。古いから学ぶべきことがないという意味ではないと僕は思ってますが、今は少し事情がかわってきています。特に、プログラミングパラダイムは、DDDが発刊された2004年当時と比較して大きく変わっていることは事実だと思います。たとえば、関数型とオブジェクト指向の融合は、ScalaだけではなくRxJSなどを利用できるモダンなJavaScriptでも同様に実用的です。最近だと、Rustもこのようなパラダイムを持つ興味深い言語です。さらに今後も、Scala/AkkaやErlang/OTPで実現できるリアクティブシステムのような考え方も、他の言語やプラットフォームに広がっていくと推測しています。こういう混合パラダイムはDDDでも示唆されていましたが、開発者の規模や安定した開発環境も確保できる時代なので、昔と違って実用的です。これらの新しい技術要素を考慮してDDDを適用していくことは、これから面白い分野になるのではないでしょうか。
リアクティブシステムの適用範囲
愛宕 リアクティブシステムの話が出たので、その話に広げたいですけれども、なぜ今リアクティブシステムが必要なのでしょうか?
加藤 リアクティブシステムは、メッセージ駆動(メソッドを呼び出し応答を待つのではなく、コンポーネント間のやりとりを非同期なメッセージで行う通信方法)を基盤しています。また、弾力性(ワークロードに応じたスケーリング戦略のこと。必要に応じてスケールアップとスケールアウトを行う)や耐障害性(障害が起こることを想定して障害から回復するための能力を備える)を可能します。最終的に即応性(高負荷時であっても、システムの一部のコンポーネントが障害を起こしても速やかに反応する)という価値をユーザに提供するという考え方です。
システム内部で障害が起きてもシステム全体がダウンしないし、ワークロードが急激に増えても即座にレスポンスを返せるというわけですから、それが低コストで実現できるのであれば技術的やビジネス的にも理想的ではありますね。最近では、そのコンセプトをScala/AkkaやErlang/OTPで実現するという方法論が知られています。ただ、リアクティブシステムの設計や運用は言うほど簡単ではありません。イノベータでの実証を踏まえてその知見をコミュニティにフィードバックしていく、まだ過渡期のフェーズであると思っています。
いずれにしても、その考え方を学ぶことは重要ですし、その基礎となるメッセージ駆動を理解しておいても損はないでしょう。メッセージ駆動の考え方は古くからあります。そのため、学ぶためのリソースは比較的多いでしょう。実際の現場では、リアクティブシステムのリの字どころか、マルチスレッドプログラミングの必要性もないというのが現実かもしれません。しかし、メッセージ駆動はマルチコアを有効活用するための有益な仕組みが備わっています。CPUのクロック数が頭打ちになっている現在、マルチコアを生かしたこのようなプログラミングスタイルは一つの解決手段として必要と言えるでしょう。そういえばMacBookのコア数は増えないですね(笑)
愛宕 増えないですよね(笑)
加藤 昔ながらのメソッド駆動のプログラミングスタイルではマルチコアを生かすのは難しいです。典型的には、マルチスレッディングと呼ばれるもので、副作用の制御やデッドロックなどの問題が起きやすい。
メッセージ駆動は、それらの問題を回避してマルチコアを生かす為の一つの方法論です。コアが複数のマシンに跨がることを考えると問題はさらに難しくなります。スケールアップとしてのマルチスレッドだけではなく、スケールアウトとしてRPCも考慮にいれる必要があるからです。こういう混合パラダイムが複雑度をあげる一因です。メッセージ駆動はそういう問題を解決しようとしています。リアクティブシステムに含まれる他のコンセプトも、昔から聞くような話が多いです。Lightbend社のCTOが体系化し名前をつけたことで、パターン言語として広く認知されるようになりました。仕事では、ScalaとAkkaを使ってリアクティブシステムの一部の概念を適用しています。
愛宕 Scalaで書くことを決めて、なおかつAkkaというフレームワークの採用は、最初の導入コストは高いですよね。
加藤 そうですね。難易度は高いですね。導入をリードできる、先生がいないとリスクが高いと思います(笑) つまり実現可能性という観点で、そういう人がいないと無謀な掛けとなってしまう気がします…。僕の職場では各分野に先生がいるので、あまり困ることはなかったですね。
リアクティブシステムを適用しやすいシステムは、高い非機能要件が問われる、基盤となるようなシステムではないでしょうか。そして、スキル的にも担保できる体制があり、ビジネス上の戦略にも合致するならば考えてみてもよいかもしれません。もちろん、そこまでのニーズがないものに対しては、リアクティブシステムを持ち込むのはやりすぎだと思います。そういった技術的な実現可能性やビジネスで見込まれる効果があるのであれば、KPIを実現するための手段として、マネジメント層に投資を提案するのもありだと思います。
エンジニアのポジショニング
加藤 僕もエンジニアなので、技術にこだわりたいという気持ちは強いです。が、仕事として提案する際は、その技術がビジネスにどれだけよい影響を与えられるかをエンジニアであっても表現できた方がよいでしょう。単に”この技術はすごいから採用したい”と素直に提案してもよいですが、比較的 技術に精通しないマネジメント層には、意図が伝わりにくいでしょう。それこそユビキタス言語がない。ビジネス上のKPIに貢献できる理由を、彼らに伝わる表現でコミュニケーションできると、結果的に自分のフィールドも作りやすいです。さらにそこで成果を出せばその技術のおかげとなるので好循環が作りやすいと思います。
まぁ、”それはマネージャーや上司の仕事だから自分は知らない”と言ってもいいですが、積極的に改善を働きかけるならば一考の価値があるでしょう。とはいえ、提案しても会社のビジョンやミッションと合わないとなるケースもあります。それはそれで、自分の方向性と合う会社を探すきっかけにもなるでしょう。方向性が異なるのに、続けても生産的ではありませんので。
つまるところ、技術にこだわるならKPIへの貢献ができるかも考えるってことですかね。転職の際は、そういうことが可能な職場を探していましたが、結果的に合致したのがChatWorkでした。
愛宕 その考え方には納得します。加藤さん自身は今後どのようにしていきたいと考えていますか?
加藤 チャットワークをよくしていくために必要な技術力をさらに身につけていくことですね。言わずもがな開発者に限らず、エンジニアリングに関係する仕事は、常に研鑽が必要だと思います。僕も余暇にテーマを決めて少しずつ学んでいます。自分の無知を知るというのは正しいことなので継続したいと思います。
愛宕 世の中色々な知識があって、流行り廃りもあると思います。その時にヤマのはり方みたいなのはあるのでしょうか?
加藤 ヤマを張って有名になれる人ならいいと思いますが、僕はそういうことをできないしやったことがありません(笑)つまり、計算したことがないんです。Scalaを始めた当初もこんなに広がるとは思っていませんでした。僕の場合は、最初に自分が面白いと素直に思えるかですね。飽きたら別のことに進めばいいし、勉強不足だなと思えることを見つけたら、それをやっていけばいいと思いますよ。書籍も読み返すたびに、知識が深みを増すのを感じれたりします。仕事で提案するならば、先ほど述べたような考え方も必要ですが、学びは純粋にエンジニアリングとして楽しめるかを重視しています。昔と比べて、和訳本より原書を読む機会が増えて一苦労だと思いますが、自分の中でそれだけ集中できるテーマがあることは幸せなことだと思います。