複雑な処理フローやロジックをミス無く実装するコツ

ソフトウェア開発では仕様で決められた処理フローやロジックの実装を行う場合がよくありますが(製品によってはプログラミングの大半を占める)、複雑な要求の場合不具合の原因にもなりがちです。

そのような場合、どのように実装すればミスが起こりづらいでしょうか。

例えば「0~9の10個の整数のうち、偶数のものを標準出力する」という要求がある時、普通に考えれば以下のように実装します。

Python
for i in range(10):
    if i % 2 == 0:
        print(i)

一方「奇数は表示しない」と考えれば、以下のようにも実装できます。

Python
for i in range(10):
    if i % 2 != 0:
        continue
    print(i)

ではどちらが良いコードでしょうか?

私は要求を素直に実装した前者だと思いますし、このような簡単なケースではほとんどの方が前者で実装すると思います。要求に偶数と書いてある以上、奇数を示す論理式が表れるのは分かりやすいとは言えません。

しかしながら、要求が複雑化してきたり、コードの改変を繰り返すうちに意図せず後者のような「要求仕様と同値と思われる」実装になっていくことがあります。そして多くの場合そこにバグが潜みます。同値の論理を別の形で書くというのは意外と難しいです。

そのような事態を防ぐには、以下のようなことを意識すると良いと思います。

  • 論理式は要求の形そのままで使う(反転したりしない)
  • フローチャートがあるなら、コードと1:1対応が見て取れるような実装にする

私は例え冗長に見えたとしても、要求仕様をそのまま書き下すような形でまずは実装するのが良いと考えています。その方が不具合を見つけても修正が容易ですし、仕様変更にも対応しやすくなります。

ですが後々パフォーマンスを高めるために実装を整理したいこともよくありますし、そもそも要求仕様自体がイマイチで、愚直に実装をした結果見通しの悪いコードになってしまうこともあります。

そのような場合にはテストを書くことが有効になります。セオリーとしてはまずは単純な形で実装してテストを通過できるようにし、仕様が固まってからテストで保護された状態でリファクタリングをすることが有効です。つまりフローの表現を製品コードではなくテストコード側で行うということです。

これはソフトウェア開発の基本のようでもあり、なかなか実現できている現場が少ないというのが実情でもありますが・・・

コメント

タイトルとURLをコピーしました