ある機能を修正した。ところがその機能を使っている状況Aではうまくいっているのに、状況Bではうまくいかなかった。
###事例1:同じ目的の異なる実装を作らないこと。
既存のソースコードの全体がうまく理解されていないときは、いつの間にか同じ機能の関数を複数実装していることがある。そのため状況Aではうまくいくのに、状況Bではうまくいかなかった。ある機能を修正したときに、それを呼び出す側の関数が状況Aと状況Bでは違っていた。そのため状況Aではつじつまの合う修正になっていたのに、状況Bではつじつまの合わない修正になっていた。
単一責務の原理を守ると、このような状況にはならなくなるし、プログラムの見通しがよくなる。
###事例2:単一責務の原理にしたがえば、多重定義はしないこと。
原因の解決にあたると、同じ「hohehoge」という名で機能を呼び出しているはずが、hogehogeが多重定義されていた。多重定義の結果、一方と他方の他方の間で食い違いが生じやすい。一方だけ実装を改変して、他方の実装を同じように改変することをしていないというトラブルを生じやすい。
C++でdefault引数を使えば、引数の個数が違うだけの実装をする必要がない。
void hogehoge(double a, double b=0.0);
ところが問題のソースコードの中では
void hogehoge(double a, double b);
void hogehoge(double a);
のようにそれぞれの関数があって、それぞれが独立に実装されていた。
このような状況は、問題が生じたときに一方だけ修正されて、別の側は違った動作をするようになっていく。だから、このような実装が存在したときは(自分が作ってしまったこともあるだろう)、default引数を使って一つだけ実装するようにしよう。
単一責務の原理はSOLIDなプログラムを書く出発点だ。単一責務の原理は理想論ではなく、実際の実務でバグを減らす経験則だ。単一責務の原理を意識するかとしないとでは、結果に大きな違いを生じる。
もし、まだ単一責務の原理を知らない人が職場にいたら、ぜひ紹介してください。