Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

2年間リアーキテクティングをして、3つのしくじり

こんにちは、エンジニアの id:i1derful です。
2020年モバイルファクトリーアドベントカレンダーの21日目の記事です。

はじめに

僕は、とあるプロダクトチームのフロントエンドユニットに所属しています。
主に何してるかですと、フロントエンド改修プロジェクトに携わっています。

フロントエンド改修プロジェクトでは、レガシーなコードをリプレイスしています。
プロジェクト内での自身の主な役割は、

  • プロジェクトの方針および指針を決める
  • スケジュールを切る
  • 遅れたらテコ入れして上長に「いい感じ」に報告して交渉する
  • メンバーの作業範囲・段取りを考えて伝える
  • 何人のエンジニアを借りれるか相談する
  • もちろん作業する

このプロジェクトはすでに2年ほどやっています。

Q: 2年やっての感想は?
A: 疲れましたね

もちろん疲れただけでなく得られたものは当然ありますよ。
失敗は成功のもとと言いますので、しくじりエピソードを記事にまとめてみました。

プロジェクトのきっかけはなんですか?

我々プロダクトチーム開発者は「モダンな環境で開発したい」思いが切にありました。

このプロジェクトは、950あるUIコンポーネント等を移植していくプロジェクトです。
先人のフロントエンド職人の方が遺した2017年のドキュメントに「脱AngularJS」の文字が読み取れます。
この「脱AngularJS」を実現するべく、当時の急先鋒であった「Vue.js」が選定されました。
その結果「AngularJS 1.x」の上に「Vue.js」が乗っかってるトリッキーな構造が仕上がりました。

この仕組みを実現しているモジュールは、社内では『変態モジュール』と呼ばれているのですが、このモジュールがなかったらフロントエンド改修プロジェクトがさらなる荒波を突き進んでいたと思います。
敬意を込めて感謝します。ありがとうございました。

月日は流れ、我々プロダクトチーム開発者は「早く Vue.js 上だけで開発したい」思いにシフトしました。

プロジェクトの目的はなんですか?

「脱AngularJS」を掲げただけでは、ゴールが不明瞭でメリットが弱かったのでした。
そのため、以下の問題の解消を目的に掲げることで、プロダクトチームの合意を得てプロジェクトに昇格させました。

  • 複雑な仕組みの単純化
    • 先ほど言ったトリッキーな構造です
  • 学習コストを下げる
    • チームを移動しただけでトリッキーに出会うのはつらいですね
  • 開発者体験(Developer eXperience: DX)向上
    • エンジニアはアーキテクチャがぐちゃぐちゃを嫌います
  • ユーザー体験(User eXperience: UX)を手早く生み出す環境整備
    • 制作範囲の外にあるトリッキーを考えず楽して作りたいものです

「脱AngularJS」は手段であって、DX向上なら生産性向上に繋がりプロダクトチームのメリットになるので目的になります。

高尚なことを言ってそうに聞こえますが、
「面倒くさいからこんな環境やめさせてくださいな」を言っているに過ぎないのです。

プロジェクトはどんな運用で動いていますか?

レガシーソフトウェア改善ガイド』の帯に書いてありました。

これは延命ではない。進化なのだ!

かっこいいですね。すなわち我々のプロジェクトもかっこいいはずです。

先人のフロントエンド職人のお力もあり、フロントの構造がモノリシックではなかったので「AngularJS のコンポーネントを Vue.js のコンポーネントに移植」が明白だったことが幸いでした。

『レガシーソフトウェア改善ガイド』において「リファクタリング」と「リアーキテクティング」は本質的に同じと説いていますが、コンポーネント移植が「リファクタリング」で完全なる「脱AngularJS」が「リアーキテクティング」に該当するでしょう。

Q: それはそれとしてシステムを止めているの?
A: いえ、稼働中に少しずつ移植しています

システムリプレイスには以下の方式がありますが、

  • 一括移行方式
  • 段階移行方式
  • 並行移行方式
  • パイロット方式

このプロジェクトは「並行移行方式」が当てはまります。
なぜ「並行移行方式」を採用しているのかは、コンポーネントを含むモジュールの数が950もあるためですね。

「一括移行方式」を採用していたら膨大すぎて大爆発する恐れもありました。問題箇所が深くなってわかりにくくなるでしょう。
「段階移行方式」を採用していたら950もあれば都度都度システムを停止することになり、プロダクトが死んでしまうでしょう。

リスクは当然減らしたいし、サービスを止めたくありませんよね。
そこで『変態モジュール』があることで、我々プロジェクトは「並行移行方式」のコンポーネント移植ができたわけです。
再度あらためて先人に敬意を込めて感謝します。ありがとうございました。

しくじりエピソード

プロジェクトを進行するにあたって、さまざまな出来事がありました。
振り返りとして反省点を3つ挙げてみます。

しくじり① 設計の正しさを体現したい欲望に取り憑かれていた

理想形も叶えたい謎のバイタリティに溢れていた時期があり、設計の正しさを体現したい欲望に取り憑かれていました。
今なら「このタイミングでやるべきことじゃない」と、優先度を考慮した上で言い切れます。

これはプロジェクト内で全会一致した、方針ではなく指針、確固たる作業指針がなかったがためと思います。
『レガシーソフトウェア改善ガイド』によれば「リライトのリスク」を軽んじていたのでしょう。
とはいえ、設計に対する考えが深まったので、やって損だったとまでは思わないですね。

しくじり② 締め切りが近くなるまで焦っていない

夏休みの宿題でしょうか。
僕は夏休みの宿題を始業式間近になって焦ってやりだすどころか、もはや提出すらしない破天荒な子どもでした。
会社員として働けていることが奇跡に近いかもしれません。

とはいえ、個人だけでなくプロジェクトメンバー全員が等しく締め切りを意識しなければならないはずです。
だからベロシティグラフを見ながらメンバーに発破をかけたりすることで進捗を安定させないといけません。
締め切りを守らないなんて組織が許しませんし、自発的に動くチームは常に改善活動でアップデートしていくはずです。
スクラムで言うところの透明性がなくては健全なチームではないですね。

しくじり③ やっぱり皮算用の見積もり精度は低い

大きなタスクは中身が見えないことから規模感の言い値で見積もりされがちなので、やっぱり精度は高くなかったですね。
そのため、プロジェクトが進行していくうちに「難易度」という物差しで工数見積もりを行い見積もり精度を高めようとしていきました。
難易度の低いタスクから中難度のタスクまではほぼほぼ見積もりどおりとは思いました。
けれど、最も難易度が高いタスクは15日かかると見積もりをしていたのですが、15日でやるにはさすがに無理をして(残業して)間に合わせる努力をしましたね。
小さく見積もりたくなる人間の弱さ(自分を優れたものとして見せたがる)が出てしまったと振り返れます。

かといって、単に見積もりを盛って、30日など大きめの数字で見積もっても、上長への報告時に「あーそんなに」という無価値なトークで時間が潰れるので難しいところですね。
大きめの数字になるなら、もっと近くのゴールがあるのでタスクを小さく分割します。
分割すると見積もり精度が上がります。

難易度の物差しを使う場合、以下のような「つらみ」が見積もり数字に反映されます。

  • 発生条件がレアな動作確認
  • 動作確認のために環境整備が必要
  • 共通化がもたらした密結合なコンポーネントの関心の分離
  • モジュール同士の依存関係がズブズブで1つずつほどく必要がある

世の中には難易度評価の手法がすでにあるので、それを元に見積もるのが楽そうです。
難易度評価をする際は、以下が必要と言われています。

  • 質的作業分析
  • 量的作業分析
  • 技術的実現性

先人は必ずいます。車輪の再発明なんて楽をしていないのでまっぴらごめんですね。

さいごに

このプロジェクトに関わっていただいた、今も関わってくれているメンバーの皆さん本当にありがとうございます。
少人数、かつプロダクトが正常に稼働することが最優先なので、プロジェクトの進行がストップすることもよくありました。

「脱AngularJS」は続きますが、終わりの目処が見えてきました。
貴方が入社されるときには「刷新されたモダンなフロントエンド開発環境」が用意されている(はず)でしょう。

しゃべってても仕方ないので、ひたむきに愚直にがんばりますね。
早く終わらせて一緒に祝杯でもあげましょう。
それではまた今度。

次の記事は id:Eadaeda さんです。