bussorenre Laboratory

hoge piyo foo bar

人間同士の通信プロトコルを見直し、ユビキタス言語で会話しよう

【Mentor Ver.】TechTrain Advent Calendar 2019 18日目の記事として書いています。

はじめまして。 @bussorenre と申します。主に業務では Scalaを利用してサーバーサイドアプリケーションを書いたり、時々terraform スクリプトを書いたりしてAWSでインフラを整えたりしています。

TechTrain の説明を少しだけさせていただくと、なんと、「無料でエンジニアになんでも相談出来る」というすごいサービスです。 メンターの方々も、メルカリやLINE 等、第一線で活躍されているエンジニアさんばっかり。

相談出来る内容も

  • 具体的な実装の相談(ReactであれこれしたいがAという問題に詰まって悩んでる)
  • キャリアの相談(副業とかどうしてるのか、就職先をどうやって決めたか)
  • 起業相談(←代表の小澤さんが趣味でやってるだけ?笑)

などなど、幅広く、むしろ私が相談にのってほしい。(ダメ?笑)

はじめに - コミュニケーションロスと向き合う

業務としてプログラムを書き始めるようになると、それまで趣味でやってた時に比べて明らかに圧倒的に「他者とのコミュニケーション量」が増えます。「この実装いつまでに終わりそうですか?」といった簡単なほうれん草から、「この仕様を実現するために、どういう設計にしようか」といった複雑な議論まで、一人で仕事が簡潔しません。

チームに人数が増えれば増えるほど、物事を伝えるということに工数が増えていき、実作業に取られる時間が減っていくなんてことが起こりがちです。

人間同士の通信プロトコルを定義しよう

人間同士で「今質問していいですか?」「いいですよ」「ありがとうございます。Aということについてなんですが…」 と会話を始めるように、TCP コネクションを張るときは 「SYN」「SYN ACK」「ACK」パケットを送信しあって、通信を始めます。

我々が普段仕事で当たり前のように使っているインターネットがこんなに広く普及してるのは、早期に「通信規約(=プロトコル)」が標準化されたからです。

インターネットの通信方法がRFCで標準化されているように、人間と人間の間にも通信のプロトコルを明示的に示すと非常に便利です。 特に、「常識」と言われていることほど、「お互いにとって常識かどうか」を確認しあうと便利でしょう。

例えば、リモートワークなどをするときは、

  • 始業時に「リモートワークを開始します」とSlackで宣言する。
  • 昼食などで離席するときは「離席しています」とSlackで宣言する。
  • 就業するときは「リモートワークを終了します」とSlackで宣言する。

というプロトコルを共有しておくと、今誰が仕事をしているのか、今誰に話しかけても問題ないのかなどがわかって便利です。

大事なのは、プロトコルのルールの中身よりも

  • 「ルールをみんなで共有している状態」
  • 「ルールの是非をみんなが納得している状態」
  • 「柔軟にルールを変更できること」

が大事です。これらができていないと、せっかくプロトコルを規定しても、それに従わないメンバーが一定数出てきてしまい形骸化してしまうからです。 形骸化したルールを早く修正しないと、プロトコルは腐ってしまいます。

ユビキタス言語を定義して、言葉の齟齬を減らそう

例えば「アイテム」という言葉を使う時、そのアイテムって一体何なんでしょうか?

  • ゲームでプレイヤーが入手できる道具?
  • 課金して購入できる商品のこと…?
  • テーブルビューの一つの要素…?

英語的にはおそらくどれも正しいですが、チームメンバーが「アイテム」という時の意味は一体なんなんでしょうか?

ユビキタス言語はドメイン駆動設計において非常に重要な概念の一つで、チーム内で共有する固有の言語です。 今から作ろうとしているシステムの仕様や動作を伝えたりする時に使用します。

何が、何と関連しているのか。何が何を操作するのか。ソフトウェアが解決すべき問題(=ドメインモデル)を定義する時に使います。

日々の人間同士のコミュニケーションでも、今話している話が「ゲーム内のアイテム」なのか「商品」のことなのか等、共通の認識があると スムーズに議論が進むことができます。

私の本業のチームでは「○○チーム用語集」という共同編集可能なmarkdown で書かれたページが有り、そこにドメイン用語を記載しています。特に、「新しいチームメンバー」が入ったときほどユビキタス言語を見直す良い機会です。

「AdminUser と OrganizationAdminUser と CustomerAdminUser の違いってなんですか?」とか「NormalPermissionとGeneralPermission って意味かぶってませんか?」等、普段使ってて感覚が麻痺している古株のチームメンバーのいい刺激になります。

先程の、コミュニケーションプロトコルの話と同じですが、チームメンバーみんなが共通認識を持っており、理想状態に近づけるために柔軟に変更できる状態が最も望ましいです。

ドメインモデルでプログラムを表現できるようにしよう

ユビキタス言語と、アプリケーションの中での表現が一致していれば、これ以上便利なことは有りません。

これは、人間同士のコミュニケーションロスを減らすだけでなく、人間←→プログラムという変換ログを少なくすることもできます。

ドメインモデルだけでビジネスロジックを表現できるようなアーキテクチャを採用すると、技術的関心事に左右されることなく、 「このソフトウェアが実現しようとしている事はなにか」ということにのみ注力することができます。

具体的には「レイヤードアーキテクチャ」「クリーンアーキテクチャ」などと呼ばれる構造を取り入れたりすることで解決に向かうことができます。

この辺を語りだすと adventcalendar 毎日書いても終わらないので、参考になったリンクを張っておきます(下部に参考書籍も載せておきます)

buildersbox.corp-sansan.com

まとめ

業務エンジニアに必要なスキルでかつアマチュアエンジニアではそこまで必要ないスキルの特徴として、コミュニケーションという課題があるなと思い、 こんな感じで記事を書きましたが、中途半端なDDDの紹介に行ってしまった中途半端な記事になってしましました…。猛省。

まぁ、実際通信を実装するのも、アプリケーション内での通信の定義がほとんどだったりしますし、自分がコミュニケーションで使ってる「プロトコル」を見直すと 良いのかなと思いました。以上です。

以下に、参考書籍のリンクを張っておくので、ぜひよかったらどうぞ。