ソフトウェア品質について思うこと

私の主観なので、考え方の1つとして参考になればと思います。

ソフトウェア品質って?

システム構築のプロジェクトをやってると、毎回こんなことを言われます。
・チェックリストの件数と密度は?
・不良の摘出件数と密度は?
・どんなバグが出てるの? 品質向上施策はしたの?

まぁ、システム開発に携わった方なら、普通に言われることと思います。

「動作不良がなく、仕様通りに正しく動作する。」

これ自体は正しいことと思います。
ただ、私としては、「これだけでは足りないのでは?」と思うわけですよ。

例えば、
仕様通りに動作するけど、ソースはスパゲッティ状態で、開発した人しか理解できないプログラム

「仕様通りに動いているので、品質は確保できている」と言えるけど、同時に「開発した人にしか理解できないソースは、修正時にデグレを起こす可能性が高く品質が悪い」
とも言える。
 結局、品質って良いの? 悪いの? ってなりますよね。

これは「品質」をどう定義しているか? の違いによるものと思ってます。


ソフトウェア品質の定義

ソフトウェアの品質には、いくつかの観点があると思います。

私の場合、下記の観点で品質を見るようにしてます。

  1. 正確性(仕様通りに機能すること)
  2. 安全性(想定外の事象が起きた時、安全な方向に処理が倒れること)
  3. 操作性(ミスを起こしにくく使いやすいこと)
  4. 保守性(機能拡張、仕様変更に対応しやすいこと)
  5. 性能(人がストレスを感じない程度に応答が返ってくること)

1. 正確性

ソフトウェアが正確に動作しないのは致命的ですから、これは必須条件です。
仕様に書かれている通りに動作しないものは、不良として検知され修正をすることになりますので、品質を評価する上で数値化もしやすく、誰もが意識していることだと思います。

2. 安全性

これは、仕様に書かれていないことをどれだけハンドリングができているか?
ということになります。
例えば、仕様で

処理済み件数と総処理件数を引数で受け取り、進捗率を返す。
進捗率は、 (処理済み件数/総処理件数)×100 で算出する

と書かれていたとします。

何も考えずにコーディングするとこんな感じだと思います。

public float(int completeProcess, int allProcess){
  return ( completeProcess / allProcess ) * 100
} 

これだと、allProcessが0の場合、例外が発生しますよね。
総処理件数とあるのだから0件はあり得ないだろうと思っても、
呼び出し元で引数が正しくセットされないこともあり得ます。
取り得る組み合わせとしては、表1の通りで、 仕様で考えられているパターンは緑色のところだけ。 赤色のパターンが発生した時、どのような処理を行うのか
を考えて処理を安全な方向に持っていくことを安全性と考えています。

表1 発生事象パターン

 引数が両方ともマイナス値だった場合、比率は正の数値を返すので、呼び出しもとでは正しく計算されたかのような勘違いをして不良に気づかない可能性もあります。

3. 操作性

画面のデザインや見た目については、個人の好みもあるので、どれが良いとは言いにくいですが、例えば、品質試験の合否判定結果を入力する画面を考えて見ましょう。



 ケース1とケース2。どちらも合格または不合格を入力する画面になりますが、どちらが操作ミスを誘いにくいか ということになります。
ドロップダウンリストの場合、マウスのホイールで選択肢が変わってしまうことも考えられますし、選択されている値で確認することになります。
一方、ラジオボタンだと選択されている値と場所で確認できるため、ラジオボタンの選択肢の間を離すことで、どちらが選択されているか視覚的にもわかりやすくなります。


4. 保守性

ソフトウェアは一度作れば終わりというものではなく、構築中でも稼働後でも仕様変更や機能追加は常に発生します。
仕様変更や機能追加の要望に対し、より少ない労力で対応できるように作られていると品質が良いと言えると思います。
例えば、売上伝票入力の画面で商品コードを入力したら販売単価を表示する処理があったとします。

特に意識せずに開発を行うと
売上伝票入力画面の機能内に商品コードから販売単価を取得し表示する処理を作成すると思います。
この時、商品コードを引数に販売単価を取得する関数を作成して、売上伝票入力の機能と分離できるかどうかがポイントになります。
関数として切り離しが出来ていれば、他の機能で販売単価を取得する処理が出てきても関数呼び出しで対応できるようになり、ソースコードの冗長性がなくなります。
コピペで処理を繰り返すのも楽ですが、後から修正が入ることになると、同じ修正を複数箇所で漏れなく実施する必要があり、テストも大変になります。

処理の内容が固有的(該当の機能できか利用しない)か汎用的(他の処理でも使える/使う可能性がある)かで処理を細分化し、汎用的な機能を切り離すと、保守性の高いものができると思います。
ただ、処理の単位をどこで区切るかによって、関数の使いやすさが変わります。
使いにくい関数は活用されず、類似の関数が乱立すると保守性が失われるため、汎用部品の設計は重要だと考えてます。(開発者の経験とセンスが試されるところですね)

あと、読みやすさ。 これも大事だと思います。
たまたまかもしれませんが、オフショアに出したソースコードは見にくいことが多くて。。。
現地の人に
「彼らは見た目はこだわらない。 見た目にこだわるのは日本人ぐらい」
と言われたこともあり、気にしすぎなのかとおも思いましたが、見にくいソースは、バグを作り込んでても気づけないと考えてます。
見やすいソースは、ロジックの違和感を感覚的に気づくこともできると思います。
どこを修正したら直るか、どこに影響がありそうかと推測することもできるので、見やすいソースは正義だと思います(笑

5. 性能

性能は、非機能要件として捉えられることが多いです。
昔はハードウェアが高価で性能も良くなかったため、ソフトウェアで性能を出す工夫がされてました。
最近では、ハードウェアの性能が上がり、少々変なプログラムを組んでも性能に影響を与えることは少なくなってきました。

人がストレスを感じ始める時間は3秒ぐらいと聞いたことがあり、性能要求でも画面処理系では、応答時間はxx秒以内とか書かれていることが多いです。

開発段階ではデータも十分に揃っていないため、性能劣化の危険があるロジックも気づかないことが良いです。

本番稼働後1-2年経ってから性能問題が浮上することもあり、ハードウェアだけに頼るのではなく、メモリの無駄遣い、多重ループ など、ソフトウェア側でも対策できることはやっておく方が良いです。


最後に

私の周りでは、ソフトウェア品質=正確であること(上記の1.)と考えてる人が多いように感じてます。

私は
「正確に動くのは当たり前で、これが満たせてるだけだと品質は20点」
 の考えで、より品質を高めるために、今できる精一杯のことやるようにしてます。

色々な人のソースを読むと、自分に足りないところを気づけるので、勉強になります。

今は、40代になると開発は無理。管理者の道しかない と言われてますが、
自分の限界は、自分で判断したい。
仕事では、会社の方針に従うことになりますが、趣味では、まだまだ開発を続けます!


コメント

このブログの人気の投稿

[Music] DTM初心者のためのドラム打ち込み その2

[Swift] StoryBoardを使用しない - UITextFieldで編集不可にする方法

[Swift] UISliderをカスタマイズしてみる