【AWS DevDay Tokyo 2019 セッションレポート】レガシーコードからの脱却 #AWSDevDay

2019.10.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS DevDay Tokyo 2019 のセッション、「レガシーコードからの脱却」をレポートします。

10/05追記  本日スピーカーの吉羽さんご本人がスライド資料付きの登壇内容ブログを公開されましたので、そちらをご確認された方が良いかと思います。

セッション概要

クラウドを活用することで調達のリードタイムは過去に比べて圧倒的に短くなり、ビジネスの変化にも柔軟に対応できるようになりましたが、このクラウドの特性を享受するためには「アプリケーション」自体も信頼性が高く、変化に対応できることが必要です。

一方で、機能を変更すると他の場所が壊れる、影響範囲が大きすぎて新しい機能の開発に時間がかかるといった、レガシーコードに起因する問題に悩まされている開発チームが多いのも事実です。

本セッションでは、そもそも最初からレガシーコードを作らないようにどうすれば良いかについて9月発売の同名書籍の内容を踏まえて解説します。

スピーカー

株式会社アトラクタ
CTO

吉羽 龍太郎さん

セッション内容

アトラクタについて

  • 開発プロセスに関するコンサルやトレーニングを生業にしている
  • 開発現場でコーチング
  • トレーニング
  • 執筆
  • 認定スクラムマスター研修主催

自己紹介

  • 2013/04 AWS入社
  • 4年前くらいに退社、独立(アトラクタ)
  • 著書、訳書多数

新刊、「レガシーコードからの脱却」の内容を話す

  • 2019/09/19発売
  • 売れ行き好調

レガシー本といえば

  • レガシーコード改善ガイド
  • レガシーソフトウェア改善ガイド
  • リファクタリング

レガシーコードとは「レガシーコード改善ガイド」の定義

  • テストのないコード
  • どんなに上手く書かれていても関係ない

レガシーコードとは「レガシーソフトウェア改善ガイド」の定義

  • 保守または拡張が困難なコード
  • コードだけでなくプロジェクト全体にも当てはまる

レガシーコードとは このセッションでの定義

  • 理由問わずに修正、拡張、作業が難しいコード
  • 保守に多額の金がかかる
  • 同じ用語でも中身の認識に相違があることが多い
    • 議論前に共通認識確認が大事
  • レガシーコードが生まれた理由は、品質は重要ではないと思われた場合が多い

ソフトウェアと変更

  • 変更有無
  • 使われない・使われる
  • 2x2で4パターンに別れる

使われるソフトウェア

  • 変更が必要になる
    • 変更予測は無理、当たらない、時間かかる
    • よって変更可能となるように書くべき
    • その逆がレガシーコード(修正、拡張、作業が難しいコード)
    • 必要になった時に対応できるエンジニアリングプラクティスを身に付ける
  • ソフトウェアの保有コストを下げたい

リリース後のバグ修正には途轍もない時間がかかる

  • 問題が見つかったフェーズ
    • 要求や設計 - 5分
    • コードやユニットテスト - 15分
    • などなど、後工程になるほど時間がかかる
  • 開発者の時間の半分以上が、過去にやった仕事の手直し
  • コードを扱いやすくして、保守コストを下げなければ

レガシーコードを最初から作らないようにする

  • 開発プロセスに注目
    • ウォーターフォール
      • 上手くいくならOK
      • 問題は、リスクが後ろにならないとわからないこと
      • 合ってる計画がちゃんとたてられる領域ならフィット
    • スクラム
    • XP エクストリームプログラミング
    • スクラムとXPを組み合わせる

ソフトウェアが生み出す成果を決める要素

  • 問題設定力
  • 開発力
  • チーム力

具体的には?

  • 9つのプラクティス
    1. やり方より先に目的、理由、誰のためかを伝える
    2. 小さなバッチで作る
    3. 継続的に統合する
    4. 協力し合う
    5. CLEANコードを作る
    6. まずテスト書く
    7. テストは振る舞いを例示
    8. 設計は最後に行う
    9. レガシーコードをリファクタリングする
  • スクラムとXPからプラクティスを抽出
  • 各項目は関係性がある

やり方より先に目的、理由、誰のためかを伝える

  • 役割の違い
    • プロダクトオーナーの責任
      • ビジネス価値最大化
      • プロダクトビジョンを周りに理解させる
      • プロダクト結果責任
      • などなど
      • WHAT担当
    • 開発チームの責任
      • リリース判断可能なプロダクトを作る
      • 設計、開発、テスト
      • 品質を満たす
      • などなど
      • HOW担当

WhatとHowを分離

  • 何欲しいか、なぜ欲しいかは顧客やプロダクトオーナーの役割
  • やり方は開発者の領域
    • 物事のやり方は一つでない。トレードオフがある
    • やり方を明示されると選択や交渉の余地が減る
    • 結果として手続き的コードになりがち
  • まず「コンテキスト」を共有、理解が大事

ユーザーストーリー

  • 何が何のために誰のために存在するかを一文で表したもの
  • 機能について会話できるくらいのかろうじて十分なドキュメント
  • 仕様書ではない
    • 会話でソフトウェア作るための理解を深める
  • 知識はドキュメントではなく、コードにまとめるべき
  • ストーリーが限定的であることで、テスト可能になる(受け入れ基準と自動化)
    • 実例による振る舞いのテストが可能に
  • シンプルに始める、追加は後で
  • ちょっとずつ進めることで、良い設計が浮かび上がってくる

小さなバッチで作る

  • タイムボックス
    • 固定の時間の中でタスクに取り組む
    • タスク分割になれるまでは機能しやすい
    • スクラムやXP
  • スコープボックス
    • 時間を重視せず、ストーリーやタスクなどの作業単位で終わらせる
    • 作業探知が比較的均一で小さい場合に選択
    • カンバン
  • 長い期間で大きな嘘をつくのではなく、短いイテレーションの中で小さな嘘をつく

QCDSの何を調整するのか

  • ウォーターフォールは可変要素が何もない
  • アジャイルは品質固定、作る量が可変
  • スコープと時間を柔軟に考える
  • リソースという単語は人間には適用できない
    • 人月の神話
  • 人を追加すると、やりとりが増えて速度が落ちていく
  • 品質犠牲にすると、後から辛い
  • スコープを調整し、価値ある機能から順番に作る
    • バックログ化

ケイデンス、リソース効率、プロセス効率

  • ケイデンス(リズム)が長くなると、リソース効率化を目指しやすい
    • 同時に着手するものが増える・タスク切り替えが増える
    • 役割分担が増える
    • 最後にテストや統合フェーズが増える
  • ケイデンスを短くするとプロセス効率が上がる
    • 同時着手を減らす必要
  • プロセス内の作業量を減らすとシステムが安定する
  • モブプログラミング = 究極の1個流し

ソフトウェアの評価

  • ソフトウェアの評価は、顧客にとって価値あるものに基づいて評価すべき
    • 価値は完成して初めて価値になる
    • 本当に価値が実現できているか
    • 価値実現までの時間が期待した通りか?
    • 部分最適化を避ける

フィードバックサイクル

  • 小さなバッチの方がFBの回数増える
    • スプリントレビュー、レトロスペクティブ、継続的統合
    • 顧客やPOと同席することでFB回数増やす
    • ビルドを高速化
  • FB対応をサポートする文化が必要
    • 価値やリスクに応じて取捨選択する

CLEANコードを作る

良くないコードの特徴

  • いっぱいある
    • 重複コード
    • 長すぎるメソッド
    • 巨大クラス
    • などなど
  • 例を挙げると限りない
    • チームで理解して、取り組む必要がある
  • 従うべきガイドラインも必要

CLEANコードとは

  • 凝集性
  • 疎結合
  • カプセル化
  • 断定的
  • 非冗長
  • テストしやすさと密接な関係

凝集性

  • 各部品は一つのことだけ扱う
  • クラスが一つの責任に集中
  • 名前をつけられるアイデアや概念になる
    • 名前重要
    • クラス名にData
    • メソッド名にCheck
    • これらはもっと具体化した方が良い
    • 自然言語に近い感じになっているのが望ましい

疎結合

  • オブジェクト間の関係を明確な意図を持った状態に保つ
  • サービスを直接呼び出すのではなく中間層を経由
    • コードにつなぎ目を入れる
  • 密結合も全てが悪なわけではない
    • 不慮の結合を避ける
    • コード品質が低い時に現れる
  • 再利用という名目のもとコード品質を犠牲にしてはいけない

カプセル化

  • 実装詳細は外から見えなくなっている
  • オブジェクト指向最大の利点
  • 呼び出し側観点で機能を設計
  • 何をやっているか示す名前をつけて、どう動くかは隠す

断定的

  • 自分の責任は自分で管理する

非冗長

  • DRY原則
  • 意図的に冗長性を組み込むことはある
  • 冗長さは状態や振る舞いだけでなく、テスト、概念、解釈なども

CLEANのメリット

  • 凝集性があれば、理解もバグ発見も簡単
  • 結合度が低ければ、低副作用、テスト・再利用・拡張が簡単
  • カプセル化されていれば、後から変更するの簡単
  • 断定的であれば、振る舞い配置する橋や依存データがある場所であることを示す
  • 冗長でなければ、バグ修正や変更は一箇所一回だけですむ

感想

面白かったです!なるほどと思う箇所が多々ありました。ソフトウェアの評価は、顧客にとって価値あるものに基づいて評価すべきの部分が一番印象に残りました。私はこれまでウォーターフォールな開発会社と自社ECサイト担当を経験してきたのですが、人月のビジネスモデルだとこれが難しかったり、顧客の価値だけで評価するとエンジニアリングの難易度、労力は考慮されなくなるのでモヤモヤしたりと、「うまくいかない感」を感じることが多かったからだと思います。様々な開発手法を学んで最適な手法を選択できるように努めたいと思いました。