Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

システム開発の現場改善記 - Template Method パターンでチームの開発工数を 1 / 10 にした話 ※オチ付

f:id:tbpg:20150522001300j:plain

概要

Template Method パターンでチームの開発工数を 1 / 10 にした話です

システム開発の現場改善記シリーズの目的

下記のリンク先を参照ください

前提

  • 10 年以上前の話
    • XP とか JUnit とかの話題が出はじめたばかりのころ
  • 当時 SI'er の下請け会社に正社員として所属。様々な現場に派遣されていた
    • 最高で 7 次派遣!
    • 自社の名刺?何それ飾り?
  • Java の開発の話。 当時 Java の経験は半年程度

目次

  1. プロローグ - 入場 -
  2. コードリーディング
  3. 提案
  4. サンプル実装
  5. 横展開向けの資料作成
  6. 実開発フェーズ
  7. 無事納品
  8. 効果測定
  9. エピローグ - その後 -

1. プロローグ - 入場 -

SI'er の下請けで働くプログラマだった私。

今回の現場は Java を用いたミドルウェア開発 です。
この案件は継続案件であり、すでに初期開発は終えているため
システム全体の仕組みはできあがっていました

このシステムは、 様々なサービス を扱います。
各サービスは 基本的な処理の流れは同じ ですが、 細かなルールが異なります

  • 上流システムから XML を受信
  • XML の内容を Validate
  • XML を出力フォーマットの XML に変換
  • XML を下流システムに送信

おおむね、上記のような処理になります。

チーム構成

開発内容

システム全体の設計は初期開発時に仕上がっており、
すでにあるサービスと似た新サービスを増やしていくだけ です。
そのため、単価の安いプログラマを中心としたチーム構成です。

状況

私は 6 名の開発者の中で一番最後に参入しました。
参入時は、各メンバーが設計書を作成しているフェーズでした。
今回の開発で 10 個のサービス を追加します。

スケジュール的には
「どうやって期間内に納品しよう?」
「無理っぽくね?」
と解決の糸口も見えないような状況でした。

設計書の作成に参加するには中途半端な時期だったため、
まずは 既存システムのソースコードとドキュメントを読んで内容を把握 するように言われました。

メニューに戻る

2. コードリーディング

そんなこんなでソースコードリーディングをはじめました。
1 つ目のサービスを読み終わったところでちょっとした違和感を覚えます。
このロジック、各サービスのクラス側にあっていいのだろうか? 」と。

しかし、 1 つだけ見たのでは分かりません。
2 つ目のサービスを確認します。ここで確信に変わりました。

1 つ目のサービスを読んだ時に気になった
「このロジック、各サービスのクラスにあっていいのだろうか?」と思った部分は
完全な重複ロジック でした。

そこで、 既存のサービスをざっと確認しました。
例外なく処理の大まかな流れは同じで、重複している箇所も同じです。

いわゆる

コピペ+差分のみ変更駆動プログラミング

による成果物です。

メニューに戻る

3. 提案

そこで、 Template Method パターン の適用を提案しました。
重複部は抽象基底クラスに移動し、 各サービスは抽象クラスを継承して仕様の 差分のみを実装 します。

この際、重複部の行数を大まかにカウントしておき、全体の開発に必要になる
コード量が 1 / 10 程度 になることを知らせました。

すると、

PM 「本当にそれができるなら、余裕で納期に間に合うので是非やって欲しい。」
PM 「まずは本当にできるかどうか、 2 サービス仮実装 して欲しい。」
PM 「詳細の作り込みは省略して、 実現可能かどうか分かるレベル で実装してください。」

と頼まれました。

メニューに戻る

4. サンプル実装

各サービスの 重複部を抽象クラスに抽出 しました。
抽象クラスを継承し、 2 つのサービスを作ります。
特に問題なくサンプルの実装が完了 しました。

ちなみに、この時点で Java の経験は半年でしたが共通部の設計などの経験はなく、
実務で抽象クラスを使ったり、デザインパターンを導入するのも初めてでした。
結城先生の Java言語で学ぶデザインパターン入門 でサンプルを書いたことがあった程度です。
実務で得られないノウハウを自習で得た成果 です。

出来上がったサンプルに問題がないことを PM に報告し、
既存のサービスとの差も確認してもらいました。

ここで Template Method パターンを利用した 重複の排除と差分実装案 が正式採用されました。

私「全体に展開するための資料を作りますね。」
PM 「そうですね。よろしくお願いします。」

メニューに戻る

5. 横展開向けの資料作成

プロジェクトに参加しているプログラマのレベルはあまり高くなかったたため、
そういったレベルでも、 迷わず実装できるよう な資料を作成する必要があります。

1 サービスを先行実装し、 このサービスの 実装手順 に関して
Word の手順書を作成しました。
そして、 Template Method パターンに関する説明資料 を作成して準備完了です。

メニューに戻る

6. 実開発フェーズ

説明フェーズ

私以外の 5 名を集め、説明を開始します。

  1. 現状のサービスと重複コードについて説明
  2. Template Method パターンについて資料とサンプルコードを用いて説明
  3. 個別のサービスの実装手順書と実装例のコードを見せながらサービスの実装方法を説明

のような手順で説明を行いました。
分からないことがあったらいつでも聞いてください 」と付け加えます。

実装フェーズ

10 サービスを 6 名で実装する必要があります。
目標は 1 人 2 サービス
PM は比較的能力が高いと思われる担当者に 2 サービスをアサインしました。
私は抽象基底クラス部分も担当します。
(実装してはじめて分かる差分もあるので、最初の実装段階で完璧ではありませんでした。想定通りですが。)

そして実装開始。
質問を受けたりしつつ、私も手を動かします。
重複部が多かったため、実際に差分で実装してみると実装量は非常に小さいです。
あっという間に終わったので、 次のサービスに手を付けます。

そんなこんなで終わってみれば

  • 私: 抽象クラス + 5 サービス
  • 他メンバー: 1 人 1 サービス× 5 人 = 5 サービス

という結果に。

メニューに戻る

7. 無事納品

重複部を共通化したことで、 開発期間は大幅に短縮
テスト対象も減り、コピペミスなどの弊害もなくなったためテストもほとんどバグがでませんでした。
期日通りに無事納品を完了しました。

メニューに戻る

8. 効果測定

納品後、障害もほとんどなく暇があったため、自分がどの程度の比率を担当したのか
ステップ数をカウントしてみました。
結果、



全体の 9 割 が私の成果物でした。
抽象クラスの 重複ロジック部がどれだけ大きかったか よく分かります。

そして、抽象クラスを作成したことで以降の保守にかかる工数が大幅に削減されました。
事実、次の改修からは 開発者が 6 人から 2 人体制に なりました。

メニューに戻る

9. エピローグ - その後 -

開発体制

2 人になり

  • PM 1 名
  • 開発リーダー 1 名(私)
  • 開発メンバー(新人) 1 名

となりました。

信頼と決定権

実績を残したことで、提案が通りやすくなり権限が強くなりました。
その後は、 JUnit の導入もすんなり認めてもらいました。

単価はビタ 1 文変わらなかったので長居しませんでしたけどね

メニューに戻る

ポイント

  • 自習 していた内容が役に立った
  • 節約できる工数をステップ数で 具体的 に示すことで、説得を優位に進めた
  • さほど難しくない Template Method パターンを適用しただけだが、非常に大きな成果を生んだ
    • そこそこのスキル でも問題を発見し行動できれば 大きな貢献が可能
  • PM が柔軟 な判断ができる人物だったことが幸い
    • 納期が差し迫っていたことが、説得に関してプラスに働いた面もある
  • これだけ成果を出していながら お金の交渉 ができない不器用だった私
    • 他のプログラマと私の単価は大差ないでしょう。むしろ多重請負の底辺だったので一番低かったかも。
  • 実績によりリーダーに昇格した

オチ

改善時は、納期が差し迫っていたこともあり無事納品をできて喜ばれましたが、
その会社は「 ステップ数見積り 」を行っている会社でした。
※この事実は納品後に聞いた。

  • テスト結果の報告時に、お客様から以前と比べて障害件数が少な過ぎることを突っ込まれた
  • 納品時に、お客様から見積りと比べてあまりにステップ数が少ないことを突っ込まれた
  • 今後の保守でお金を取りにくくなったこと

に関して、 PM が上層部からチクチクと文句を言われましたとさ。

知らんがな。

親記事