こんにちは、CCIのくっちーです。 広告案件管理システムのWebアプリの開発、運用を担当していました。 (現在は別プロダクトを担当しています。)
今回は設計を見直して、技術的負債を減らす取り組みについて書いていきます。 この記事はCARTA TECH BLOGアドベントカレンダー 12/18の記事です。
背景
担当システムではコードのレガシー化が進んでおり、技術的負債をどのように減らすかという課題に直面していました。ソースの変更が少なければ問題無いですが、大幅改修依頼があったため改善が必要でした。
私は改修機能を担当していたため、設計、実装を行うことになりました。
改修内容
ユーザ同士がやり取りするメッセージ機能を改修しました。
以下のユーザー要望を実現することが目的です。
- 複数メッセージを同時に確認できる画面が欲しい
- 既存では1メッセージしか確認できないため、新規画面が必要
- メッセージ機能を1対多ではなく、1対1でやりとりできるようにしたい
- 既存では1対多でのやりとりのみ可能
進め方
システム全体に影響する課題のため事業部外の知見を得たいと思い、CTO相談室にアドバイザリを依頼しました。
今回は、少しずつ再設計を進めます。
既存のアーキテクチャは既存設計と新設計が共存する構造になっています。
まずはメッセージ機能から再設計を行い、それ以外の機能は順次対応するようにしました。
現状の把握
まずはレガシー化している原因を調査しました。
メソッドの依存関係が多く、修正時に影響が大きくなる
共通処理以外のメソッドが複数箇所から呼び出されていました。
例えばAメソッドを修正した場合、呼び出している5箇所全てに動作確認が必要になることもあります。
また依存関係が多いと単体テストが書きにくいため、既存実装では単体テストの作成が難しくなっていました。
権限処理が散らばっている
権限処理がフロントエンド、バックエンド両方に分散して書かれている状況でした。
処理分岐、ループ処理が多くなり複雑で認知負荷が高い実装になっていました。
再設計について
チームでルールを決めて進めていきました。
ルールだけだと共通認識を持つことが難しかったので、 CTO室にソースレビューを依頼しました。設計方針に沿った実装になっているか見て頂きました。
1.権限ごとにエンドポイントを分ける
クライアント、バックエンド両方でエンドポイントを分けるようにしました。
before: 全権限の処理が1つにまとまっているので処理が複雑になりやすい
after: 権限ごとにエンドポイントを分けると、分岐処理が減るのでシンプルになる
2.バリデーションと権限制御を切り出す
今回はバックエンドで権限制御を行うので、 httpリクエストを受け付けた時にバリデーションと権限制御を行うようにします。
before: 認可処理とvalidationが分散しており、ビジネスロジックに絡まっておりテスタブルでない
after : 認可処理とvalidationをまとめ、ビジネスロジックと分けたことで個々がテスタブルになった
3.責務を明確にする
各レイヤーごとの責務を明確にしました。
before: 明確に決まっていなかった
部品によって各レイヤーの責務が異なっていました。
after: チームで責務を統一
各レイヤーの責務は以下になります。
バックエンド
各レイヤー | 責務 |
---|---|
バリデーション | 必須チェック、入力項目のチェック等を行う |
認可処理 | 権限制御を行う |
Controller層 | httpトランザクションのみ行う |
Converter層 | Service層から受け取った値を、レスポンスの形式に成形する処理 |
Service層 | ビジネスロジック |
Model層 | DBのCRUD処理を行う |
フロントエンド
再設計した機能はAPIで取得した値を表示するシンプルな機能だったので、
責務は画面描画のみで、ロジック、データ整形は行わないようにしました。
よかったこと
複数の課題を解決することが出来ました。
- 条件分岐やループ処理が大幅に減ったため、可読性が向上
- テスタブルな実装になり、単体テストが書きやすくなった
- 今後の改修コストの削減
- 手動テストの工数を削減
- 修正時の影響範囲を小さくすることが出来た
課題
- クライアントの権限制御
- 画面のパスではなく、権限制御の共通ロジックにまとめた方がよいかも
- バックエンドのService層の責務が大きすぎる
- 責務を細かく分けた方が良さそう
- 複数の設計が共存しているので、新規参画者は把握しづらい
感想
CARTAは横のつながりがあるので、有識者と気軽に相談出来るのでありがたいです。
これからもレガシーコードを改善する機会はあると思うので、積極的に改善していきます。