引継いだソースコードを大幅に改編した。そのときの経験を述べてリファクタリングと改訂の参考にしたい。
従来記事
の続きです。
###大幅改変の必要性を吟味する
大幅改変は趣味でするもんじゃない。改変をすると新たなバグを埋め込む危険があるし、下手なやりかたをすると壊してしまうだけになる危険がある。小規模に少しずつリファクタリングをしていって、次第にきれいな構造のプログラムにしていくことの方がはるかにいい。
不幸にして、用いているアルゴリズム上の問題で性能がでないことが判明したので、やむなく大幅改変せざるをえなくなった。
###名前空間 namespaceを導入する。
ソースコードを改変する際にはその変更の範囲がどこまで及ぶのかを見極めることが必須です。名前空間を導入することで、それがどの範囲の機能なのかが明確になっていきます。
また、名前空間を導入したことと対応して、ソースコードのディレクトリ構造も見直します。置き換える予定コードと置き換え後のコードは別のディレクトリに入れておきます。
###開示するAPIを明確にする
その引継いだコードがもっているの中で、改変対象のコードのうち開示するAPIを明確にしていきます。そうすると、そのAPIを利用する上位層についてはコードの改変の影響が及ばなくなります。
###別アルゴリズムバージョンの名前空間と開示するAPIを明確にする
別アルゴリズムに置き換えるからといって、使い方は同じであるべきです。ですから、名前空間だけちがって、APIは同じメソッド名、関数名を持つように考えていきます。このようにすることで、別アルゴリズムバージョンの公開すべきAPIが明確になります。そうすれば、それより下層の実装については別アルゴリズムの方で好きに考えて実装すればよくなります。
###アルゴリズム自体は自然な実装にして、上位層の事情を持ち込まない
新規に開発する別アルゴリズムは、極力自然な定義・実装をしよう。その全体のプログラム固有の事情
などをアルゴリズム自体の中に持ち込まないように心がけよう。自然な実装であれば保守するのも、テストするのも簡単になります。ソフトウェア部品としてみたときにも再利用性を損ないにくくなります。
###公開するAPIとアルゴリズムの自然な実装の間には層を設ける
アルゴリズムの自然な実装と、全体のプログラムの固有の事情とを結びつける層(layer)が必要になります。このような層の存在によって、アルゴリズム自体の記述している層を、固有な事情によって汚染させることなく、記述することが可能になります。公開するAPIを絞り込んであることで、下位の詳細な実装に直接不必要にアクセスことを防止します。
###互換ライブラリを作り上げる
このようにして作り上げた互換ライブラリをテストします。そうして完成度を上げていきます。
###元々のアルゴリズムと入れ替える
既に関数のAPIをそろえて開発してあるので、利用する関数、クラスの名前空間を入れ替える程度で、元々のアルゴリズムと入れ替えることができます。
その時点の改変が少ないものであるので、大幅入れ替えがうまくいかない場合には、引き戻すことが可能です。
###完成度を高める
旧来のアルゴリズムを新しいアルゴリズムに書き換えたときには、まだ試しきれていないことがあるものです。十分な結合試験をして問題をつぶしていきます。そうして、実用になる水準にしていきます。
これが、引継いだソースコードを大幅改変したときの私の経験です。このような経験が皆さんにも役立つことを期待します。
追記:
ソースコードのモジュールの依存性を調べるには、Doxygenでdotを使ってincludeファイルの依存性を調べていきます。この#include "some.h" などは本当に必要なのかと思ったら、その行をコメントしてビルドできるかをで確かめています。不要なincludeを見つけるもっと気の利いた方法があればと思っています。
大幅改変する前に:
チームで共同開発しているコードは、自分の所有物ではありません。チームメンバーと十分に意見交換しておきます。変更がいろんなところに影響を及ぼしそうな改変は、それが妥当な内容であっても、実施するタイミングがあります。
追記:
大幅改変をするときには、その前の版の限界を十分にだれにでも分かるように記録を残しておきましょう。 その経過が分からない人にとっては、「前のバージョンで十分だったんじゃない」などというということになりやすくなります。
追記:
言語によっては不要なimport があるとbuild できないとか、
言語と開発環境によっては、不要なimport が色違いで表示されるとかある。
C++でも可能なようだ。良い開発環境を使おう。
たいがいの場合、良い開発環境を使うことは、開発効率の向上・コードの品質の向上につながって元をとることができる。
https://pleiades.io/help/clion/unused-include-directive.html