派生開発と機種展開の進め方

組み込みソフトの開発現場では、新規開発より派生開発のほうが、実務上の件数の面で多くを占めます。機種展開を重ねるたびに、ソースコードが機種ごとに枝分かれしていきます。そのたびに同じ修正を何箇所にも入れる負担が、現場に積み重なっていきます。本記事では、派生開発が難しくなる理由を解説します。あわせて、影響範囲の把握から回帰テストまでの実務の進め方を、手順に沿って示します。

派生開発とは何か

組み込み機器は、同じ基本機能を持ちながら、仕様の異なる機種を数多く展開します。汎用のパソコン向けソフトウェアとは、この点が異なります。ハードウェア構成や搭載機能が、機種ごとに変わる点が背景にあります(「組み込みソフトと汎用ソフトの違い」参照)。センサや制御機器では、上位モデルと廉価モデルを同時に展開することも珍しくありません。1つの製品カテゴリの中に、数十種類の機種が並ぶ場合もあります。

派生開発とは、既存製品のソースコードを土台にする開発を指します。土台をもとに、機能追加や仕様変更、機種展開をします。ゼロから設計する新規開発とは異なり、動作実績のあるコードを引き継ぐ点が特徴です。既存モデルの回路構成や通信仕様を流用し、検出性能や表示機能だけを変更する進め方が典型例です。過去の量産実績があるコードを土台にするため、動作面での安心感を得やすい進め方でもあります。

開発期間の短縮や、動作実績のある処理を再利用できる点が、派生開発が選ばれる主な理由です。しかし派生開発には、新規開発では意識しづらい難しさも伴います。開発期間の短さゆえに、この難しさが見過ごされやすい点も見逃せません。

派生開発が難しくなる理由

派生開発が難しくなる背景には、共通する複数の要因があります。長年にわたって機種展開を重ねてきたソースコードほど、次の課題が表面化しやすくなります。

  • 元のソースコードを書いた担当者が、すでに異動や退職で担当を外れています。設計意図を確認する手段が残っていません
  • 仕様書が更新されておらず、実際の動作とドキュメントの内容にずれが生じています
  • 変更の影響範囲を読み切れず、直したつもりのない箇所まで壊れてしまいます
  • 機種ごとにソースコードが枝分かれし、同じ修正を何箇所にも繰り返し入れることになります
  • 条件分岐用の#ifdefが増殖し、コードの見通しが悪くなっていきます

組み込み開発には、メモリ容量や処理速度の制約が大きいという事情もあります。限られた資源の中で機種差分を扱おうとして、無理な作り込みが積み重なりやすくなります。結果として、修正のたびに調査に時間がかかり、開発リードタイム全体を圧迫します。一つの機種でつまずいた設計上の無理が、後継機種にもそのまま引き継がれてしまう点も厄介です。

こうした課題は、機種展開を1世代重ねるごとに、少しずつ蓄積していきます。個々の修正は小さくても、何世代も積み重なると全体の見通しは急速に悪化します。派生開発の難しさは、1回あたりの変更量ではなく、積み重ねの量として表面化します。着手が早いほど、対策の選択肢も広がります。

派生開発を進める実務の手順

派生開発を進めるうえでは、変更要求を明確にする作業から着手します。何を変更し、何を変更しないかを、最初に線引きする必要があります。ここを曖昧にすると、後工程で手戻りが発生しやすくなります。実務でよく踏まれる手順は、次のとおりです。

  • 変更要求を整理し、変更する部分と変更しない部分を明確にします
  • 変更に着手する前に、現状の仕様を正しく理解します。ドキュメントが不足している場合は、ソースコードから現状の仕様を書き起こします。この手法はスペックアウトと呼ばれます
  • 変更が波及する影響範囲を、関連する処理やデータまで含めて洗い出します
  • 洗い出した影響範囲を踏まえて変更設計し、その後にはじめてコードへ手を入れます
  • 回帰テストを実施し、変更していない部分の動作が壊れていないことを確認します

この手順を体系化したプロセスに、派生開発プロセスがあります。XDDPと呼ばれ、eXtreme Derivative Development Processの略です。ソフトウェアプロセス改善のコンサルタントであった、清水吉男氏が提唱しました。要求を記述するUSDMと、作業手順を図式化するPFD、この2つの技法を組み合わせます。変更範囲を明確にしながら開発を進める考え方であり、書籍やセミナーを通じて長年紹介されてきました。

変更設計を経てからコードに着手する流れは、新規開発の設計段階の考え方と共通します(「開発の全体像と手戻りを防ぐ設計」参照)。派生開発だからといって、いきなりコードを書き換えてよいわけではありません。短納期の案件ほど、この手順を省略したくなります。しかしそれこそが、手戻りの温床になります。手順を踏む時間を惜しんだ結果、結局は手戻りで時間を失う、という逆説がよく起こります。

機種展開でソースを枝分かれさせないための設計

機種展開のたびに、ソースコード一式を複製するケースがあります。その場合、修正のたびに全機種分のコードを書き換える必要が生じます。機種数が増えるほど、この負担は加速度的に膨らみます。負担を減らすには、設計段階での工夫が欠かせません。代表的な工夫は、次の3点です。

  • 全機種で共通する処理と、機種固有の処理をあらかじめ分離して設計します
  • 機種ごとの違いを、ソースコードの複製ではなく設定データで吸収します。設定ファイルやパラメータなどが該当します
  • 複数機種を1つの製品系列としてとらえます。共通資産と機種ごとの可変部分を分けて管理する、プロダクトライン的な考え方を取り入れます

これらの工夫を取り入れると、機種が増えてもソースコードの実体は1つに保たれます。修正が必要になった場合も、対応箇所を共通部の一箇所に絞り込みやすくなります。設計時点でこの分離を意識できるかどうかが、数年後の保守負担を大きく左右します。すでに枝分かれしたソースコードでも、共通部を後から切り出す取り組みには価値があります。ただし共通部の切り出しには、一定の設計工数がかかります。機種展開の計画段階から検討しておくことが望ましい進め方です。

たとえば、通信プロトコルや基本的な制御ロジックを、共通部にまとめます。表示文言や検出しきい値といった機種ごとの違いは、設定データ側だけに持たせます。共通部を厚くするほど、新機種を追加する工数は小さくなっていきます。

回帰テストは派生開発の生命線

派生開発では、変更していない部分の動作を保証する回帰テストが欠かせません(「エンバグを防ぐ回帰テスト」参照)。ある機種向けの修正が、別の機種の動作に影響することがあります。その影響がないかを確認する工程が、常に必要になります。この確認を怠ると、市場に出た後で不具合が表面化するおそれがあります。

回帰テストは、修正した箇所そのものを確認するリテストとは、目的が異なります(「リテストとリグレッションテストの違い」参照)。リテストは修正箇所そのものの確認です。一方の回帰テストは、修正の影響が及んでいないはずの範囲まで、広く確認する点が特徴です。この違いを理解しないまま計画すると、必要な確認範囲が抜け落ちてしまいます。

テスト工程の位置づけ自体は、新規開発と共通する部分が多くあります(「V字モデルで学ぶテスト工程と品質保証」参照)。しかし派生開発では、展開している機種の数だけテストケースの組み合わせが増えていきます。機種数と機能数がそれぞれ増えると、確認すべき組み合わせは掛け算で膨らみます。機種数が二桁を超えるころには、手動でのテスト実施だけでは到底追いつかなくなります。

回帰テストの範囲を絞りすぎると、確認漏れが残ったまま出荷することになります。逆にすべてを毎回手動で確認しようとすると、開発スケジュールが破綻します。派生開発では、この板挟みが機種展開のたびに繰り返し発生します。そして現場の負担として蓄積していきます。

仕様書がない旧機種への向き合い方と自動化の必要性

旧機種の仕様書が残っていない場合には、実機を動かして得られる入出力を記録します。それを基準として比較する手法があります。この考え方は、特性化テスト、あるいはキャラクタリゼーションテストと呼ばれます。変更後のコードが、同じ出力を返すかどうかを確認します。仕様書がなくても、回帰テストの土台をつくれる方法です。ドキュメントが揃っていない旧機種を扱う場合の、現実的な出発点になります。

機種が増えるほど、回帰テストで確認すべき対象は増え続けます。手動でのテスト実施を前提にしていると、テスト工数が開発全体の進行を圧迫します(「自動テストのメリットと役割分担」参照)。機種展開を続けながら品質を保つには、回帰テストを自動で回せる環境を整える必要があります。機種が増えても、テスト工数を一定に保つ仕組みが求められます。

派生開発は、今後も組み込み開発の中心であり続けます。変更の手順を守り、回帰テストの体制を整えることが大切です。それが、機種展開を重ねても品質を落とさないための土台になります。地道な積み重ねが、長期的な保守負担の軽さにつながります。

まとめ

派生開発は、既存ソースを土台に機種展開を進める、組み込み開発の主要な形態です。変更要求の明確化から影響範囲の洗い出しまでの手順を徹底することが大切です。加えて回帰テストを徹底すれば、ソースの枝分かれや可読性の低下を防げます。機種が増えても品質を保つには、回帰テストを自動で回せる環境づくりが欠かせません。

組み込みソフトの世界 トップへ戻る