やっと梅雨が明けましたね。通勤時間の10時でも暑い、暑い。日中外で働いている方には頭が上がらないです。
今回は6月末にリリースされた「チャット部屋を閉じる際の条件強化」に関して、エンジニアの小川さんに突撃インタビュー!
今回の開発の山場や工夫点、今後の改善につなげたい点など語っていただきました!
NoSchoolではエンジニア採用も積極的に行っているので、興味ある方は「話を聞きに行きたい」からご連絡ください!
-今回はエンジニアの小川さんにお話を伺います!今回リリースした機能の内容を簡単に教えて下さい!
初めてマナリンクの機能を知る方もいると思うので、簡単に今回のリリース機能の背景を先にお伝えします。
マナリンクには、「チャット」という機能があり、先生とご家庭ユーザーの間で開設されるチャット部屋の中で授業などに関わる様々なやりとりを行なうことができます。(ラインみたいなものをイメージしてもらえればと思います)
チャット部屋は、不要になった任意のタイミングで先生・ご家庭の双方から閉じることが可能なのです。ただ、授業の予定を管理することのできるカレンダー機能のリリース以後、先生からの授業報告やご家庭側からの承諾を待たずにチャット部屋を閉じることができてしまうことが原因で不都合が生じる場面がありました。
なぜかというと、マナリンクでは、先生からの授業報告をご家庭(生徒側)が承諾することで先生に売り上げが発生する流れを取っているため、承諾を待たないでチャット部屋を閉じてしまうと、システム上では売り上げが発生しない形になってしまいます。そのため、簡単にチャット部屋を閉じることができないようにする、条件を強化する必要がでました。
今回リリースした機能では、このチャット部屋を閉じる際に幾つかの条件を追加し、その条件を全て満たしている状態でないと部屋を閉じることができないようにしました。また、条件を満たしていない場合は、画面上にモーダルでなぜ部屋を閉じることができないのかの理由が表示されるようにしました。
‐そうなんですね!確かに授業が終わったと思うとチャット閉じてしまうかもしれませんね。どんな表示がでるかなど画像で見せてもらうことはできますか?
もちろんです。
画像のように、チャット部屋を閉じようとした際、閉じるための条件を満たしていない場合には満たしていなかった条件が箇条書きでユーザーに表示されるようになっています。
-開発を始める前に、技術的に一番ネックだと思ったことはなんですか?
チャット部屋を閉じる際の条件判定をどのように設計するか、
今後の仕様変更等でチャット部屋を閉じる際の条件が増えたり減ったりする可能性があるため、いかにして拡張・改修しやすいように実現するかというのが自分の技術的にはネックになると感じました。
-今回の機能の開発を初める前と開始後に、「技術的に一番ネックだったこと」にGAPはありましたか?
ありましたね。
タスク着手当初には見えていなかったことに後から気付くことがあったため。
今回、要件としては「チャット部屋を閉じる際に条件に照らして、条件を満たさない場合には部屋を閉じられないようにする」というシンプルなものなのですが、マナリンクには「家族であるユーザー同士を紐付けることができる」という機能があり、保護者ユーザーが自身の子ども(生徒ユーザー)を家族として自分に紐付けるということが可能であり、この家族紐付けをした状況下では、「保護者と先生のチャット部屋」を閉じられるかを判定する場合、ある条件においては判定対象を「保護者」ではなく、「その保護者に紐付いている子ども」の情報を見に行かなければ適切な条件判定をできないことがわかりました。
一番最初の仕様の洗い出し時点ではこの点までは見えておらず、開発途中でこのことに気付くことになったため、このことまで考慮した上で実装を進めることになった点はGAPのあったポイントだなと思います。
‐今回の開発の山場など苦労したことを教えて下さい。
山場は2つありますね。まずは、
チャット部屋を閉じる際の条件判定をどのように設計するかという点。
チャット部屋を閉じる際に満たす必要のある条件は要件として複数個あり、その複数個全てを満たしたときに初めて閉じることができるというのは前述の通りですが、今後その条件部分が変わりうることも見越して設計を考えるべきだと感じていたため、ここは大きな山場でした。
また、チャット部屋の条件に引っかかった場合にバリデーションエラーメッセージをどう生成するかというのも苦労した点です。
チャット部屋を閉じられるかの条件判定の際、最終的には「閉じられる」か「閉じられない」かの2択にはなるのですが、閉じられない場合、「閉じられない」の中でもどういう理由で部屋を閉じることができないのかをメッセージとして画面側に返す必要があり、このメッセージをどう生成するかという部分も悩みどころでした。
‐今回の開発機能の技術的な工夫点を教えて下さい。
「チャット部屋を閉じる際の条件判定」と「条件を満たさず部屋を閉じることができない場合のバリデーションメッセージの生成」を元々は同じクラス内で行なうようにしていたのですが、バリデーションメッセージを使用するのは主に画面側の都合であり、「条件判定」の中でメッセージ生成まで行なってしまうのは少し違和感があるように感じたため、最終的には「条件判定した結果」をバリデーションメッセージ生成用のクラスに渡し、そのクラスでメッセージ生成を行なうようにすることで責務を分けるように実装しました。
‐開発中に個人として気をつけていたことがあれば教えて下さい。
色々あるんですが、「チャット部屋」という機能に対してしっかりと向き合うのは恐らく今回が初めてだったため、タスク開始時点でチャット部屋に関するドメイン知識を深めるため、Webページから触ってみたり、アプリを動かしたりしてチャット部屋についての知識を深めるところから始めました(このおかげで仕様策定段階で漏れていた事柄に気付くことができたりと色々とメリットがありました)。
また、全体感の見えにくい規模が大きめのタスクでは毎度おなじみになってしまっていますが、開発初期段階での上長への相談などをよく行なっていました。今回は新規にAPIを生やす必要があったので、その新規に生やす予定のAPIについて、「どういう目的で作るのか」「APIのエンドポイントは」「HTTPメソッドは」「誰が叩くのか」「リクエストボディは必要か」「レスポンスボディはどういう形になるか」などなど、Slackのworkflowという機能を用いて相談をするなどしました。
あとは既に述べている通りですが、チャット部屋を閉じる際に必要となる条件が増えたり減ったりしたときでも比較的改修しやすくなることを心がけていましたね。
それに、テストコードをたくさん書きましたね。「誰が」「誰と誰の部屋を」閉じるかによってケースが複数ケースあったため、実際に動かして動作確認をするよりもテストコードをしっかり書くことでこのあたりの実装の正しさを担保するようにしていました。コード量だけで見ると、Pull Requestの書いたコードのうち約半分程度がテストコードのコードでした(笑)。
‐リリース前とリリース後に「エンジニアチーム」として技術的な面で変わったことはありましたか?
個人的にはあったと思います。
今回のこのタスクが直接のきっかけというわけではないですが、このタスクの完了から少しした後、改めて、バックエンドにおける「役割」はどういったものに細分化することができるかという話し合いが起こりました。
自分はDDDについてとりわけて詳しいというわけではなかったため、改めてそれぞれクラスがどういった役割を持っているかということが整理されたのはとても学びになりました。
‐今回の機能のリリース前とリリース後に「個人」として成長した部分はありましたか?
今後チャット部屋の条件が増えたり減ったりした際にも変更がしやすいように、今後の改修まで明確に意識して実装を行なうことができたのは成長したポイントだったように思います(ただ最後に後述するが、もっとより良い設計ができたはずだと今では感じています)
‐今回リリースした機能が80%の完成度だとして、残りの20%でどのように発展していきたいか教えて下さい。
チャット部屋を閉じることができるかの条件判定部分と、バリデーションメッセージの生成部分はもっとより綺麗に設計することができたのではないかと思っています。
なぜかというと、今回設計面で特に自分の中であやふやだったのは、チャット部屋を閉じることができるかの条件判定をした際に、その当てはまった条件に関してバリデーションエラーメッセージを生成する必要があった部分です。
部屋を閉じる際の各条件判定と、画面用のメッセージ生成とは分けたほうが責務として分割して良いと考え今回は分けることにしたのですが、「条件判定クラス」と「メッセージ生成クラス」を分けたことによって、今後追加の条件が増えた際には、この2つのクラスを整合取るように改修する必要があります(正確には「条件判定クラス」と「メッセージ生成クラス」の間を繋ぐためのDTOクラスも用意したため、正確には3つのクラスを改修する必要がある)。
今回のこの要件について、改めてより綺麗に設計するにはどうしたら良かったかについて自分なりに考え直し、社内勉強会等で共有してより今回の設計に関する学びを深めることができたら良いなと感じました。
補足として、一つ今考えている案を挙げておくと、「チャット部屋を閉じる際の条件」という単位でインターフェースを定義し、「チャット部屋を閉じる際の条件判定(複数条件をまとめて)」を担うクラスではそのインターフェースの集合を扱う形にし、この2つは常に安定している単位としてまとめて扱うことができれば、各条件の詳細はその条件インターフェースの実装クラスに委ねられるので、条件の追加や削除がしやすくなると考えています。
また、バリデーションメッセージの生成についても、条件インターフェース内でメッセージ生成用メソッドを定義することで、「条件を満たさなかった場合はメッセージ生成」ということが各条件クラス内部で完結するため、条件クラスの中で必要なことが全てまとまるのではないかと構想を膨らませています。
小川さんありがとうございました。
インタビューのように設計から実装まで関わっていただけるフェーズです。
「これをやってはいけない」ということはないので、いろいろ経験したい方、提案したい方、是非一緒にNoSchoolで働きませんか?「どんな仕事ができるんだろう?」と興味がある方是非、まずカジュアルに話しましょう!話を聞きに行きたいからご応募下さい!
株式会社NoSchool's job postings