ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

「バグ」の定義について

2014-12-02 22:28:34 | プログラミング

Kokudoriさんという方が、例外 Advent Calendar 2014という大変興味深いアドベントカレンダーを書き始めていらっしゃいます。
自分はJavaで例外機構を使ってはいるものの、その理論については特に考えたことは無いので、とても面白そうです。

その1日目ですが、「バグ」という言葉について、「必ず起きる失敗はバグ」という定義をしていました。(追記:後述しますが、バグという言葉を定義していると思ったのが勘違いだったようです)
これは今まで自分が聞いたことがない定義だったので、びっくりしました。自分が思っていた定義は以下のようなものです。

  • アプリケーションが仕様書に沿った挙動をしない場合は「(製造)バグ」
  • 設計書が上位の設計書(最終的には、顧客が本来望んでいた動作)を満たしていない場合は「仕様バグ」

つまり、どんなに変だと思う挙動や処理失敗が起きたとしても、仕様書に載っている動作であれば(製造)バグではありません。

プログラムを実行した際に起こる「失敗」は、予測可能なものと不可能なものがあります。
例えばファイルを読み込む場合、そのファイルが無い可能性があります(これは予測可能でしょう)。ファイルが無かったらどうするのかは、設計書に書くべきことです。ファイルが無かった場合に設計書に書かれた動作が行われれば、それはバグではありません。(設計書と異なる動きをしたら、バグです)
一方、設計書にファイルが無かった場合の動作が書かれていなかったら。ファイルの読み込みは失敗し、設計書に書かれている動作(ファイル読み込み)は出来ませんね。これを製造バグと呼ぶか「設計書にそもそも挙動を書いておけよ」という意味で仕様バグと呼ぶかは悩ましいですが、いずれにしても、この設計書にはファイルが読み込める前提でしか書かれていないので、それが実現できておらず、バグと言えると思います。

逆に言えば、設計書は、予測可能な失敗に対しては どういう動作をするか書かなければなりません。
そこから漏れて実行時に起きる失敗(つまり予測できなかった失敗)がバグです。
(想定外の入力があった場合の動作を「未定義」あるいは「不定」と書いておけば、そういう入力に対して何が起きても“仕様通り”となりますw) 

ちなみに、予測可能な失敗、というか設計書に対処方法が書ける失敗は、自分は「エラー」と呼びます。
エラーに対する対処ロジックは、エラー処理、あるいは異常系の処理と呼びます。
バグに対しては(そもそも予測できないので)設計書に対処方法を書けません。(書けるのであれば、それはバグではなく、エラーです)


Kokudoriさんが書かれている「バグにソフトウェアが対応すべき責任は無い」というのは理解できます。
プログラム自身がバグに対応する(バグを修復する)ことは無い、という意味だと思います。
自分のバグの定義では、責任が無いというより、そもそもバグは設計書に対処方法を書けないので、バグに対する処理をプログラミングすることも出来ない、ということですが。

ファイルが無かった場合に「大抵の場合これはバグとは呼ばれません」というのは、自分の定義に従えば、「大抵の場合、ファイルが無かった場合の動作が設計書に書かれているので、バグとは呼ばれない」です。前述の通り、設計書に記述されていなかったら、バグと呼びます。


失敗の発生頻度によってバグか例外かを分ける考え方は初めて聞いただけに、自分の頭ではいまいちピンときていません。
なので、とりあえず、自分がどう考えているかだけ書いてみました。

追記:Kokudoriさんからお返事をいただきました→Gist


追記2:
必ず起きる失敗はバグという名前で呼ばれています」という文章の意味を自分が勘違いしていたようです。
これを、「必ず起きる失敗≡バグ」、つまりバグの定義「バグとは、必ず起きる失敗のことである」と解釈したのですが、そうではなく、「(どんな条件下でも常に)必ず起きる失敗は、バグである(バグ以外の何者でもない)」というニュアンスだったようです。
(で、バグは例外処理の対象外である(別のレイヤーに属している)、という分類になる) 


詳細設計書は必要でしょ

2014-03-16 12:37:24 | プログラミング

不定期に不死鳥の様によみがえる話題、今週は「詳細設計書不要論」でーす(笑)

もちろん自分は詳細設計書は必要だと思っているが、SIerの仕事において、という前提がある。
一人で要件決めから実装まで行うなら設計書なしでもいい。
しかしSIerの仕事、つまり「発注者から依頼を受け、複数人で開発するプロジェクト」は、設計書が無いと成り立たないと思う。
(あと、自分はウォーターフォールモデルを前提にしていてアジャイルは知らないが、アジャイルでも設計書という呼び方ではないかもしれないが設計書相当のものはあるはずだと思う) 


自分が考える詳細設計書の使い道は、以下の通り。

1.【設計フェーズ】発注者に対して処理内容を説明する(承認をもらう)
2.【実装フェーズ】実装者に渡して実装してもらう
3.【試験フェーズ】出力結果を検証する
4.【保守フェーズ】現在の仕様(過去の経緯)を確認する

順序として、設計フェーズ→実装フェーズ→試験フェーズ→…→運用・保守フェーズ と考えている。
(試験にも色々種類があるので、実装フェーズに含まれる部分もあるかもしれないけど) 

1は、要するに詳細設計書のレビュー。
レビューするのは発注元の企業であることもあるかもしれないが、一次SIerであることの方が多いと思う。
実際に詳細設計書を書くのが二次SIer以下であっても、一次SIerが確認・承認して責任を持つものだと思うが。ただ単に伝言ゲームをするだけだったら(以下略)

2は、“実装”以外に説明する言葉を知らない^^;
実装者側も、何を作ればいいのか示してもらわないと作りようが無いからねぇ(笑)
複数の実装者が居る場合に、設計書抜きで(口頭で?)何を作るか指示するとか、ありえないでしょう。

3は、単体テストになるのか結合テストになるのかはよく分からないけど。
ブラックボックステストの入力データおよび期待される出力結果は、詳細設計書から抽出する。
設計書に書かれていることが正しい(その為に事前に設計書レビューを行って承認を得ている)ので、作ったプログラムが設計書通りに動くかを確認するのがテストの目的だと思っている。
(ちなみに、受け入れテストは発注者の思っている通りになっているかを確認するものだと思うが、この「思っていること」が文書化されていないと揉める原因になるよなぁ) 

4は、運用・保守に入ってから、現状の仕様を確認するという想定。
バグっぽいと思われる動きを見つけたり仕様変更をしたりしたい場合に、今の仕様がどうなっているのかを確認したくなるのはよくあること。
まぁ、紙(設計書)に書かれていることが本当に実装されているかどうかが疑われて結局ソースを見ることになる、というのがほとんどな気もするけど^^;

1~3については、詳細設計書はそのフェーズより前に必要。
4については実装後の話になるので、仕様を確認できる資料がありさえすれば、詳細設計書である必要は無い。
むしろ、実際に動かしてから分かった知見や注意点などをまとめた資料はあると便利なのだが、それは設計書ではないわなぁ。
(設計書を書かずに実装して、後から実装を見ながら設計書を作るという話もちらほら聞くが(苦笑) 「プログラム説明書」なら、後から作ってもおかしくないと思うんだけど) 


「詳細設計書は不要」と言う人の話を聞いていると、「それは詳細設計書の内容がおかしいんじゃないか?」と思うことがある。

実装したプログラムと1:1になるようなドキュメントは、自分は詳細設計書ではなく「プログラム仕様書」と呼んでいる。
プログラム仕様書はまさにプログラムと1:1になるようなイメージで、メソッド名やら引数やら変数名まで書く。あるいは日本語で書いたプログラムのようになる。
そして、プログラム仕様書だったら、それは要らないと思う。

自分は、詳細設計書は1バッチあるいは1画面につき1つずつ作るイメージでいる。
画面の場合は、例えば入力画面→確認画面→完了報告画面という一連の流れで1つの詳細設計書、というくくりは出来るかもしれないが。 

で、詳細設計書には、どういう入力からどういう出力をするか、を書くものだと思う。
入出力先はファイルだったりDBのテーブルだったり画面だったりする。さすがにこれが具体的でないと実装のしようが無いので。
出力内容は、要するにどういう演算をするか、ということになる。ここを具体的に書くと、場合によってはプログラムと1:1に近くなることもあるかもしれないが、それは仕方ない。
それと、詳細設計書は発注者の業務内容を表しているものであり、発注者に確認してもらう必要もあるので、処理内容は発注者が使っている言葉(つまり日本語)(業務ドメインと言うの?)で書くべきだろう。

詳細設計書における処理内容の記述では、「どういう演算を行うか」を書くべきであり、「演算をどうやって行うか」は書くべきではない

例えば明細テーブルから指定された顧客の金額A,金額B項目のそれぞれの合算値を取得したいとする。SQLっぽいイメージで言うと「select sum(金額A), sum(金額B) from 明細 where key=顧客番号」みたいな。
(プログラマーだと、SQLの方が分かりやすいし誤解が無いよねー(笑))
ところが、実装方式としては、「select sum(金額A) from 明細 where key=顧客番号」「select sum(金額B) from 明細 where key=顧客番号」とSQLを2回発行しても望む結果は得られる。
あるいは、「select 金額A, 金額B from 明細 where key=顧客番号」で集計前のレコード一覧を取得し、取得した側で合算を行うことでも望む結果は得られる。
どの方式でもやりたかったこと(明細テーブルから指定された顧客の金額A,金額B項目のそれぞれの合算値を取得)は満たしているから、詳細設計書の期待する通りに実装されていると言えるだろう。
必要なのは設計書通りにシステムが動いていることなのだから、どう実装されているかは関係ないのだし。(設計書は発注者にレビューしてもらって承認を取っている前提なので、開発側としては「設計書通りにシステムが作られている」のを目指すことになる)
(余談だが、今の例は単純なので一番最初のselect文がいいと思うが、DBサーバーの負荷が高くて集計処理はさせない、という現場もありうるorz(あくまで可能性の問題ですじょ?!)。それだと一番最後のselect文の方がいい。でも将来DBサーバーが良くなったら、最初のselect文に変更してもいいだろう。どちらであっても詳細設計書上に書かれている仕様は満たしている。しかしもし設計書上にSQL(実装方式)を書いていたら、その他の方式のSQLは仕様を満たしていないということになってしまう)

もちろん、実際に実装する際に実行効率や保守効率が悪いプログラムを作るのは良くない。
でも実装レベルのそれは、プログラマーの実力やソースコードレビューで担保するものであり、詳細設計書とは別の話だと思う。
(したがって、プログラマーは“ただ単に詳細設計書の日本語をプログラミング言語に変換するだけの作業者”ではない)

プログラマーの質が低いことを想定して詳細設計書に実装レベルの話まで盛り込むのは筋が違う。
実装レベルの話を書きたいなら、詳細設計書でなくプログラム仕様書を書くべき。(プログラム仕様書を書くのは机上でコーディングするに等しいので、本当に無駄だと思うが)

(もっとも、自分も詳細設計書にプログラマー向けのSQLを書いたこともあるけどね^^;
保守フェーズに入ってからの追加開発とかだと実装イメージの方が先に浮かぶし、実際にSQLを書いて実現可能性を検証できるし伝える際も誤解が無いし。とは言え詳細設計書の本文に堂々と書くのはやりすぎなので、詳細設計書がExcel方眼紙だった!のをいいことに、セルのコメント機能で埋め込んでた(爆)) 


予想通り長くなってしまったので、これくらいにしておきます^^;

本当は、
・(「詳細設計書」という)言葉からイメージされる内容が人によって違うので、それをどうやって統一すべきか(教育の問題)とか
・設計書に業務ドメインで物を記述するなら、SEにはプログラミングの知識よりも業務知識が優先されるというSIerの考え方にも一理ある?とか
・とは言え詳細設計書に実現不可能なことを書くわけにはいかないので、実現可能かどうかを試すの(プロトタイピング?)はどこでやるべきなの?とか
・実装レベルの品質を上げる(各プログラムの統一を図る)為にフレームワークを用意したりコーディング規約を定めたりサンプルを用意したりレビューを行ったり徹底させたりする人(自分はそれをアーキテクトと呼んでいる。SIer内の上級プログラマーとして目指すならアーキテクトかなぁ)が必要だよねとか
の話も書きたかったけど、まぁ機会と気力があったら。


プログラムの品質と価値

2013-12-30 13:44:58 | プログラミング

今年読んだどこかのブログを見て思ったことを思い出したw
プログラムの品質と価値について、そのブログでは、「品質」の評価基準に「価値」を含めているようだった。

プログラムの「品質」と「価値」は別物だと思う。
プログラムの「品質」っていうのは、例えばWebアプリなら、24時間365日稼動し続けられるとか、大量のアクセスがあっても落ちないとか、インジェクションっぽい入力をされても大丈夫とか、そういう事だと思う。
一方、「価値」は、ユーザーにとって便利であるとか、(そのプログラムを動かすことによって現れる)サービスを提供する企業にとっては収益が高いとか、そういう事だと思う。

そして、品質と価値は全く無関係という訳でもなくて、品質が悪ければ価値は下がる。でも品質が良いからといって価値が高いとは限らない。
便利なサービスでも落ちまくってたら評判(価値)は下がるし、全くバグの無いクソゲーは品質は高いけど価値は低いよね(笑)

ちなみに、「UI(ユーザーインターフェース)がクソ」とかいうのは、プログラムの品質というよりはサービスの品質だと思う。
プログラムは、あくまでサービスの仕様(要件)を満たすように作るものだから、仕様を満たしていればプログラムの品質としては合格。
つまりサービスの品質が悪いというのは、プログラムの品質が悪い場合と、そもそも仕様が悪い場合があるってことかな。

ユーザーやサービス提供企業が欲しいのは「サービスの価値」の方だから、「価値」を重視するのは当然だろう。
でもプログラムを作る側(SIerとか)にとっては、「プログラムの品質」を担保するのが第一の仕事だと思う。(メンテナンスしやすいプログラムにする、というのもプログラムの品質のひとつだと思う。これは「サービスの価値」とは全く関係ないが)
「価値」の担保をSIerに求めているとすれば、それは筋が違うと感じる。
(SIer側の戦略として、自らの意義を高める為に「価値」の領域に手を出すのはありだとは思うけど、「品質」を高めるようにするのが本業だと思う(というかまずは最低ラインをですね・・・^^;))

このように、「品質」と「価値」は別々の意味で使うので、品質と価値をどちらかに含めて考えるのは良くないと思ったのでした。 


ちなみに、どういうものが価値になるかを考えるのは、当然サービス提供企業だよね。それを考える気が無いというなら、みんなが大好きなコンサルという手もあるけどw
自社が何を提供するのかを考えないなら、何の為の会社なんだか。金だけ出す?
さらにお金も出さないとしたら、何なんだろうね?^^;


OSSのサポートとは

2013-12-01 11:11:11 | プログラミング

Asakusa Frameworkのアドベントカレンダーの1日目を書いてて、ついでにOSS(オープンソースソフトウェア)について書きたくなったのでw

OSSの厳密な定義は知らないんだけど^^;、「ソースが公開されているソフトウェア」という事だと思う。
したがって、そのソフトウェアが無料で使えるかどうかとは直接は関係ない。(無料で使えるOSSの方が多いと思うけど)

ソースが公開されているので、何か問題があったらソースを自分で調べることが出来る。
場合によっては自分用に改造することも出来る。
というのがOSSだと思う。

そして、自分でそういう事が出来ない人は、他の人に頼んでやってもらうしかない。
他の人に頼んだら報酬を支払うのも当然。(特に仕事なら)
「OSSのサポート」というのは、「あなたが出来ないこと(対象ソフトウェアの調査改修等)を引き受けますよ」という商売なので、有償なのはおかしいことではない。(対象ソフトウェア自体が無料であっても) 

ちょっと前に、絵描きに絵を頼む際の支払いとか自治体が何かを無償で募集するとかコンピューターの修理をタダで引き受けてはいけないとかの話が話題にあがっていたけれど、自分が出来ないことを他人にやってもらって正当な報酬を出さないのは、やっぱりおかしいよね?


XtextによるAsakusaFW独自DSL実験

2013-09-14 23:59:59 | プログラミング

独自DSLのエディターを作るのにXtextがあまりに便利なので、ふと思い立ってAsakusa FrameworkのBatch DSL・Flow DSLの独自言語を作ってみた。

DSLの定義とハイライト(色付け)アウトラインの表示・基本的なソース整形まで、1日で出来た(笑)
Batch DSLの方は、バッチクラス(本来のJavaのBatch DSL)を生成するところまでやってみた。

DSLの見た目はとりあえず問題なさそうだけど、入力補完が出来ないと、やはり便利ではない。
Batch DSLの場合はJobクラス(Flow DSL)自体を補完する必要があるし、Flow DSLはオペレータークラスやメソッドを補完する必要がある。
JobクラスやOperatorクラスを探す部分を作るのは大変そう。

それと、(忘れてたけど)オペレーターは色々な種類の引数を定義できるんだよね。
これをDSL上で表現するのも面倒(やり方は分かっているので、本当に面倒なだけ)^^;

という訳でかなり簡単に独自のAsakusa DSLは実現できそうだけど、実用性はよく分からないので、とりあえずここまで。


本家のAsakusa DSLは、Javaをホスト言語とする内部DSLとなっている。
オペレーターをJavaで書くので、それを呼び出すFlow DSLもJavaで作ると、Javaのエディターの機能(クラスやメソッドの入力補完)がそのまま使える。
やはり内部DSLにもメリットがある。