|
漁師プログラマ 山崎敏 YAMAZAKI Satoshi
vol.03 |
|
|
●ある日 |
|
|
ある日,新しい仕事はJavaで書くことになったのです.その理由は「前の人が書いていたコードがJavaで,しっかり動いているし,今回の仕事はその延長になる」というものでした.漁師プログラマ(注)としては,未踏の地を行くよりも,すでに誰かが歩んだ道があるのはありがたいことです.とくにその当時,Javaという言語は新しい環境であり,最新のオブジェクト指向言語であると期待もされていた時期だったので,実績のある情報は1つでも多いほうがありがたかったのです.ひととおり仕様を聞き,そのJavaのコードをなんとか参考資料として持ち帰ることができたのですが.この後,筆者は驚異の事実を目の当たりにするのです.
Javaのコードは1ファイル1クラスであることが基本のようです.よって,1つのクラス内のデータ(メンバ)をアクセスするための関数(メソッド)群は1つのファイルに書くことになります.そして,筆者のもらったJavaのコードはなぜか1つだったのです.筆者は一瞬,ファイルを開こうとする手を制止する「見えない力」を感じました.しかし,筆者はその見えない力を断ち切り,そのファイルを開いたのです.
そ,そこに現れたのは,な,なんと,1ファイル14万行のソースコードだったのです.筆者は自分の目を疑いました.「まさか,1クラスではないよな」と調べてみるのですが,どうやら1クラスで14万行….その中に複数のメンバ関数があり,1つ1つのメンバ関数もかなり大きい.クラスのメンバ変数はグローバル変数のように扱われていました.
要するに,オブジェクト指向の思想はかけらもなく,すべて関数という仕様で書かれていて「Javaはクラスとメンバ関数の形でプログラムを書く」という単純な理由から,すべての関数を強引に1つのクラス(1つのファイル)に詰め込んでいたのです.
この異様なソースコードを前に筆者はしばらく呆然となりました.しかし,せっかく手に入れた参考資料です.このファイルを印刷してみることにしました.しかし,朝から始めても一向に印刷が終わる気配がなく,夕方になって筆者はある重大な決断をしたのです.「ダメだ,もう紙がない.このコードは見なかったことにしよう」.削除!
その後,予想どおり地獄の日々が展開されるのですが,筆者は今でもあのときの判断は正しかったと確信しています.
漁師プログラマという職業をしていると程度の差こそあれ,このようなシステムに遭遇することがあります.コードの再利用とはいったい何を示すのでしょうか?本当に実現できるメリットのある話なのでしょうか?
注)理論ではなく実践(動いてなんぼ)を優先しているのプログラマのこと.筆者の造語.
|
|
|
●●コードの再利用 |
|
|
●コード内再利用とコード外再利用
皆さんが再利用というと,やはりライブラリやコンポーネント,DLLなどを利用するというイメージが多いのではないでしょうか.しかし,もっと身近なところで,たとえば自分の書いたコードをコピー&ペーストしてみたり,マクロを書いたり
#define MAX(A,B)((A)>(B)?(A):(B))
関数を書いたり
void foo(){...}
クラスをインスタンス化したり
class Boo{...};
テンプレートだって使うでしょう.デザインパターンに至っては考え方やインターフェースを再利用しているわけで,実際プログラマの多くにとってコードの再利用とは「再利用するコードを書くぞ!」と気張らなくても,いままで自然にやっていたことの延長だったりするわけです.
しかし,コード内では頻繁に再利用作業をしていても,ほかのコードへ再利用しようとなると,やはり壁が高くなるようです.とくに仕事としてのコードの再利用の優先度は低く,気合いを入れないと書けないとか,時間が取れないという話も聞きます.
本連載第2回の「コードのメンテナンス」でも書きましたが,可読性を上げようと努力することで,人に見せられるコードに変わっていきます.可読性が上がるとバグが減りメンテナンスもしやすくなり,そして再利用もしやすくなるのです.結局,再利用できるコードというのは,読みやすく理解しやすいコードがコンパクトにまとまっていることが重要だと思います.
第1回の「いかにして,バグらないか?」の回では,コードレビューが重要であるとも書きました.
コードレビューをするということは複数人のコードの情報(書き方とか考え方のレベルまで)をやりとりするわけですから,ある意味で高度なレベルでコードの再利用をしているとも言えるわけです.
そんな意味で,コードの再利用とは,ライブラリ化やDLLの利用だけが「再利用」という概念ではなく,もっと広い意味を持っていると認識していただきたいのです.その上で,コードの可読性や,コードレビューの重要性を認識していただければ,バグは減り,メンテナンスが楽になり,コードの再利用ができると,まさに夢のような開発環境への道が開けてくるわけなのです.

●関数化
プログラミングの概念の基本中の基本に,関数という概念があります.この関数の設計方法(と言うほど大袈裟なモノではないけど)は2タイプに分かれるようです.
@ コード量の増える関数化
A コード量の減る関数化
の2つです.コード量の増えるタイプの関数化を表すと図1の左のようになります.
図1の左は一筆書きの要領で,同じところは一度しか通っていません.もともと,一本道であったコードをわざわざ関数化してわざと難しく書いているようにも見えます.コード量を増やして関数化しているわけです.あるところでは,このような1度しか呼ばれない関数を大量に作っていました.筆者には「コードが長くなったので,とりあえず機能単位に分割した」としか思えませんでした.結局そのことにどんなメリットがあるのか筆者には理解できませんでした.このように,元のコードが増える方向への関数ではなくて,コード数の減る方向への関数化が正しい設計の方法だと言いたいのです.
一方,コード量の減るタイプの関数化を図に表すと図1の右のようになります.
とくにデータの隠蔽という観点から見ると,1度しか呼ばれない関数のために多くのデータを引数に載せたり,グローバル変数にしてデータを渡すのは,デメリットばかりが増えるようにも思えます.これが1度しかインスタンス化されないクラスであったらまだわかります.そこには,データを隠蔽するというメリットがあるからですが,1度しか呼ばない関数のメリットとはいったいなんでしょうか?
|
|
|
●●コード再利用の勘所 |
|
|
●共通の概念
コードの再利用は難しいというのが現状だと筆者は認識しています.「いや,そんなことはない!ライブラリなど多くの資産を現時点でも再利用しているではないか!」とおっしゃる方もおられるでしょう.筆者もその点に関しては同感です.ただ,ライブラリのように部品化できない部分に関してはまだまだ再利用が難しいと思うわけです.
コードの再利用を考えたときに重要になってくるのが,何が常識なのか?何が抽象なのか?何が共通の認識なのか?という問題だと思います.ある部分を部品として切り出したり,オブジェクト指向の概念に合わせてブラックボックス化し不必要な情報を隠蔽したとしても,そのでき上がったモノを再び使うには,その使い方の概念が広く一般的でないと使われないのです.作った本人であれば使い方を把握しているでしょうが,それが他人の作った部品となるとなかなか簡単には使わないのではないでしょうか.作った本人であっても,時間がたてば忘れてしまいます.使われないと,そのまま消えてしまうことになりかねないということです.モノがモノとして定着するには,他人と共通の概念がないといけないわけです.
たとえば,どんなに高機能なケータイがあったとしても,その使い方を知らない人には意味がないのと同じように,どんなに高機能なライブラリがあったとしても,その使い方を理解できない人には意味のないモノになるのです.「マニュアルを読めば良いではないか!」という意見もあるでしょう.しかし,ケータイのマニュアルですら,ちゃんと読んですべての機能を使いこなしている人は少ないのです(実は筆者がそうです).漁師プログラマとしては,何ページもマニュアルを読まないと使えないライブラリより,自分で同じ機能のコードを書いてしまったほうが早いと考えることもあるわけです.
多くの人が電話の使い方を知っているのは,すべての電話の使い方が共通で,簡単だからだと思います.皆さんが電話に対する「共通の概念」を持っているわけです.車の運転でも同じです.すべての車が「共通のインターフェース」を持っているから簡単に使えるわけです.同じようにライブラリの作り方に関しても「共通の概念」を無視することはできないと思うのです.
●トップとボトム
一般的に,より抽象的な概念をトップ,逆に具体的な概念をボトムとするようです.おそらく,ピラミッドの構造をモデルにしたためであると思います.ソフトウェアの設計に関しても,
・トップダウン:より上位の抽象的な概念から徐々に細かい具体的な概念へ砕いていく方向
・ボトムアップ:より具体的な概念から徐々に大まかな抽象的な概念へまとめていく方向
の2種類の方法があります.コードの再利用という点からみると,実際には完全にボトムアップであると言えるでしょう.現在「ライブラリ」という部品群はボトムの部分に対して機能を提供しているわけですし,ボトムの部分から共通化可能な部品を切り出してライブラリ化されていくのが自然な流れであるとも言えます.
しかし,ボトムの部分であれば何でも再利用可能かというとそうでもなくて,たとえば「ファイル」とか「文字列」とか「時間」とか「日付」の概念は共通的ですが,共通的な概念にあてはまらない各システム固有のボトムな部品もあるわけです.何がなんでも共通化しようとか,すべての部品を再利用可能な状態にしておくという方向性は,おそらくコストのわりにパフォーマンスが悪く,無駄な努力になるのではないでしょうか?どの部品が再利用可能な価値があるのか,共通の概念として成り立っているかをよく見極めてから再利用の作業にとりかかると良いでしょう.
ボトムではなくてトップに近い部分では,なかなか共通化したり再利用したりできないという認識が多いのではないでしょうか.しかし,最近は今まで注目されていなかったトップの部分にこそ再利用の価値があるように思います.それは,インターフェースやデザインパターンなどの,いわゆる「考え方」の再利用です.もしかしたら,ボトムの部品よりも再利用できる息の長い部品になるかもしれません.
それは,コードの再利用では,コンパイラなどの言語を越えた再利用までは難しいものの,考え方の再利用はコンパイラの種類を越え,あらゆる言語で使えるという意味も含んでいます.
●イテレータというインターフェース
筆者は,C++のSTLという標準テンプレートライブラリを知ったときに,とても感激しました.今では,なぜ感激したのか詳しくは覚えていないのですが,とにかく新しい領域に踏み込んだ感じがしました.中でも,イテレータという概念に強く惹かれました.イテレータという考え方は,コンテナクラスであれば共通に持つことになるインターフェースを定義し,その共通のインターフェースをイテレータと命名したように思えたのです.新しい言葉とともに新しい概念を知った思いでした.その昔,オブジェクト指向を知ったとき,メンバとメソッドの固まりをクラスという形で命名しても良いことを知ったことに匹敵する新しい言葉と概念でした.
デザインパターンの中にもイテレータという言葉と概念が存在します.これは偶然の一致とは言えないまでも,考え方はSTLのイテレータと同じ言葉と概念なのです.ここで言いたいのはどちらが先なのか?という問題ではなくて,コードの再利用は「インターフェースで共通化する」といった新しいフェーズに入ったように思うのです.新しい概念が加わったと思うのです.
今までの再利用の歴史を振り返るとこういうイメージです.
@ マクロでコードを共通化
A 関数でコードを共通化
B 構造体でコードを共通化
C クラスでコードを共通化
そして新たに
D インターフェースでコードを共通化
という概念が加わったと思うのです.
インターフェースが新しい概念とは言っても,難しい話ではありません.簡単に言えば「実体のないメソッドの固まりをインターフェースという形で命名してしまおう」というそれだけのことです.とくにJaveのユーザであれば,とっくに知っている概念だと思います.ただ,これからはそこをメインに再利用する道が広がっていくのではないでしょうか.
インターフェースと動作実績再利用というと中古車というイメージを持つ人も多いのではないでしょうか.しかし,多くの人は中古車のメリットを知っていても,新車のメリットも同じくらい知っていて,どちらを選ぶか悩むわけで,結局「新しいほうが良い」と思う人も多いでしょう.
では,こういうたとえはどうでしょう.
あなたが近い未来に,宇宙ステーションに行くことになりました.その乗り物として2つの選択肢が用意されました.1つは「スペースシャトル」ですでに7回の宇宙旅行をした「中古品」です.あなたが乗るのは8回目の再利用になります.もう1つは,資金をふんだんに使った「最新型の超高性能ロケット」です.乗り心地は最高.最新の機能もふんだんに盛り込まれています.ただ,まだ一度も使っていない「新品」であるということです.もちろんちゃんとテストはしています.設計者が保証してくれます.さて,どちらを選びますか?迷いますか?筆者なら迷わずスペースシャトルに乗ります.なんと言っても実績のないモノに自分の命を乗せたいとは思いませんから.
では,ソフトウェアの場合はどうでしょう?とくにソフトウェアの場合,金属疲労などの老化現象はありません.一度正しく動いたコードは,2度目でも100度目でも正しく動きます.それでも再利用が敬遠されるのは,やはりインターフェースの問題,使い方の問題があるからと思います.たとえ100万回動いた実績があるコードであっても,その使い方が不明であれば,やはり不安なわけです.いくら実績のある「スペースシャトル」であっても,使い方(運転の仕方)がわからなかったら,乗りたいとは思いませんよね.逆にインターフェースがはっきりしていて,簡素であれば,動作実績が少なくても容易に再利用できるとも言えます.我々は無意識のうちに再利用可能なコードとして,インターフェースが簡素であってさらに動作実績のあるコードを望んでいるわけです.逆に言えば,インターフェースが複雑で,動作実績のないコードは嫌われるということです.
|
|
|
●●生産性とは |
|
|
コードの再利用を行うときに品質やコストの話がなぜか必ずのように出てきます.単純に,再利用した場合としなかった場合で比較するのに,数字で比較したほうがわかりやすいからでしょう.ここで,それらの項目にも少し触れたいと思います.
●コストパフォーマンス
正確な図でないのですが,あるモノ(プログラムやシステムも含む)を開発や制作した場合のコストとそのモノのパフォーマンスを図2に示してみます.おそらく,ほとんどのモノがこの図のような曲線になると思われます.まず,コストがゼロの場合はモノはできないわけですからパフォーマンスはゼロです.ある程度のモノができる点aまでコストをかけると製品のパフォーマンスが上がり始めます.
aからbの間はコストをかけるだけパフォーマンスが上がります.しかし,bを超えてコストをかけても徐々にパフォーマンスの上がり方が鈍化していきます.最終的にはコストをいくらかけてもパフォーマンスに影響が出なくなるのです.この図で重要な点は,いかにして,点b(図でいうと,もっとも角度の広い点)を見つけるか,ということにつきると思います.それは最低のコストで,最大のパフォーマンスをあげることに繋がるわけです.
簡単な話としては,旅行に行く場合のコストとその旅行によって得られるパフォーマンスや,食事をするときのコストとパフォーマンス,パソコンを買うときのコストとパフォーマンス,皆さんの中にはそれぞれのパフォーマンスの基準があり,その基準によってコストとパフォーマンスを瞬時に判断していると思います.そしてコストが安いと思えば買い,高いと思えば買わないわけです.
ところが,ソースコードの再利用を考えたとき,なぜか,このコストパフォーマンスの図は無視されて,ひたすらに理想を追求しコストをかけるか,もしくは,まったくコストをかけないか,両極端な傾向が見られます.パフォーマンスは無視してパフォーマンスは上がるのであろうという推測や希望だけでコストをむやみにかけてしまったり,逆に,パフォーマンスはゼロであると決め付けてまったくコストをかけなかったりするようです.
コードの再利用などの部品化作業はコストがかかるのは目に見えるのですが,パフォーマンス(メリット)が見えない(見えにくい)のでこの部分を明確にすることが最初の関門であると思います.
ちなみに,コストとパフォーマンスの単位が価格などの同じ価値の単位であるなら,45度以上の角度に点bがある場合は,ビジネスとして利益の出る関係を示しているように思います(筆者の中の感覚的な話なので,数値的な裏付けはなにもありません).
●プログラマの生産性とは?
プログラマの生産性はコード量で計ることが多く,よく使われているのが「ステップ数」という量の測り方です.簡単に書けば「行数」なので,Perlのように1行にたくさんの処理を詰め込むスタイルでコードを書くと生産性は落ちることになったりします.中には,コメントのみの行はカウントしないとか,空行はカウントしないとか,ローカルなルールが多く適用されていたりします.もっと言うと,デバッグ用のコードをカウントしないというのもあり,そんなに削ってしまったら元のコードの半分以下になってしまい,ひどい場合は全行数の1/4になってしまう場合もあったりします.なんか,それってひどくないですか?10年以上の間,漁師モードでコードを書いてきた立場から言わせていただけるなら,適切なコメントは十分価値のある情報で,それなりの労力もかかっているわけです.さらには空行であっても,適切な位置の空行は「見やすくなる」という価値を持っているのです.さらにデバッグ用のコードであっても,メンテナンスなどに有効になる場合も多いので,それらの有効であり労力のかかっているコードを削るようなローカルなルールは漁師プログラマの敵であると言えます.
そんなルールは適用せずに,純粋に行数もしくは「ソースファイルのバイト数」を生産量としてカウントして良いと思います.いや,そうすべきです.
そうすることによって「生産性に反映されないから,コメントやデバッグコードは書かない」といったネガティブな思考からなる品質の低下を正しい方向へ変えることもできると思うのです.
●コードの再利用を奨励するルール
もっと言わせてもらうならば,ライブラリ化(部品化)や,オブジェクト指向の正しい適用を行い,コードの再利用性を多くしようとすると,コードの繰り返しは少なくなり,コード量は減る方向に向かうわけです.これも同じように「生産性としてカウントされないのならライブラリ化せずに,ダラダラと同じコードを繰り返し書いてしまおう」というネガティブな思考になってしまいがちです.そこで,ライブラリ化されたコードを再利用した場合でも,再利用したコードを新規に書いたコードと同じようにカウントすることで,品質の面でもポジティブな方向へ向けることができると思うのです.
実際の問題として,コードの再利用というのは品質を上げるために有効な方法であると思いますが,何も考えずに再利用できるわけではなく,それなりの労力をかけて,内容を理解したり,正しい適用ができるように工夫したり,動きの確認を行うテストコードも書いたりしながら,再利用を行うわけです.
これらの正しいと思われる品質の向上への方向性が「再利用したコードは生産したとは言わないだろう」の一言で失われていくのは,認識が薄いのではないか,と嘆きたくなる思いです.
|
|
|
●●品質とは |
|
|
●バグは回避できる
生産性と並んで,もう1つ大きく問題になるのが,やはり品質です.品質は重要だとは言いながらも,具体的に数値化できないのがもどかしいところです.プログラムの品質と言えば,どのくらいバグが出たのか,また今後どの程度のバグが出るのか,という話になると思います.たとえばMTBF(平均故障間隔:Mean
Time Between Failure)や,MTTR(平均修復時間:Mean Time To Repair)を適用してみるのも良いアイデアかもしれません.
しかし,ソフトウェアには基本的に「磨耗する」とか「消耗する」という概念はないので,バグが平均的に出てくるような状態はむしろ大問題で,それこそ設計に問題があるのではないか,とか,テストの量が不十分だったのではないか,と開発環境や開発者が疑われるわけです.ですから,一度完成したシステムには1つでもバグがあってはいけないわけで,それこそ1つでもバグが発見されたら,まだまだいるのではないかと疑われるわけです.
実際,バグにはレベルというかその威力によってバグの重要度が違います.システムが落ちる/止まる,周りのシステムにまで被害を及ぼす,場合によってはデータを破壊する,これらの症状はかなり重傷なバグです.漁師プログラマとしてもっとも避けるべきバグです.とくに,実環境でのテストをどのくらいやったのかという問題になるでしょう.
もう少し軽度のバグになると,システムは動作しているがある一部分の機能が動作しないレベルになります.運がよければほかの正しく動く機能を組み合わせることでうまく回避できたりします.このレベルでもちゃんと動作テストをしていれば発見できるものが多いと思います.
最後に,一番軽いバグとしては,機能としては問題はないが詳細な部分が違っているレベルで.表示される文字が間違っているとか,メッセージ番号が違うとか,初期値が違っているとか,おもにデータに関する部分になります.
より重要度の高いバグに重点をおいて設計すべきですし,テストすべきです.
とにかく,バグはテストをすれば回避できます.
テスト漏れ以外のバグはめったにありません.何度も言いますが「テストさえすれば品質を保てる」これがソフトウェアだと思います.「バグ=テスト漏れ」これに尽きると思います.
●なぜバグが出るか
ではなぜバグは出てしまうのでしょうか?その答えは「テストをする時間がない」のです.テストをしたいとは思っていても納期が迫ってきて,十分にテストができないということなのです.時間さえあればテストもできるしバグも撲滅できるのです.
これは,プログラマの能力というよりもむしろ管理者の能力の問題です.ただ,やみくもに「今週中にやれ!」「徹夜してでもやれ!」「期限は厳守だ!」「倒れるまでやれ!」では守れる納期も守れなくなります.何の根拠も説得力もないわけです.これでは品質を上げるどころか開発チームもバラバラで何一つうまく行かないでしょう.設計が遅れ,コーディングが遅れ,結果としてテスト期間がなくなり,バグが出る.そういうパターンなのです.管理者はとにかく日程の確保を最優先にすべきです.なぜ設計が遅れるのか,なぜコーディングが遅れるのか,そこを考えて対策するのが管理者の役割です.とはいえ,すべての責任が管理者に集中するのではなく,やはりそのプロジェクトに関わったすべての人に均等にかかってくるものと思います.
たとえテストの期間を確保できても,テストの量が多くては期間内に終わらなくなってしまいます.
しかし,テストの量はテストの方法や設計の方針によって減らすことが可能です.逆に,効率を上げないと無駄にテスト期間が長くなり,結局テストが終わらずに品質の悪いコードになってしまいます.テスト件数とは組み合わせなので,あらゆるケースの組み合わせをテストしようとすると爆発します.爆発したら最後,テストは終わりません.「時間がないので,単体テストはやめて全体テスト(システムテスト)で代用しよう」という考え方が爆発させるのです.むしろ,この考え方ではバグは取りきれません.本連載第1回の「いかにしてバグらないか?」にも書いたのですが,できるかぎり小さなコードで「単体テスト」することをお勧めします.
●時間が必要
ソフトウェアに限らない話ですが,とくにソフトウェアの開発には「開発終了」という概念が薄いです.「いくら時間をかけても,すべての時間を使い切ってしまう.ならば与える時間は少ないほど良い」などというわけのわからない理屈もあるようです.
どんなモノでも最低限の品質を確保するにはそれなりの時間が必要です.プログラマの腕は,この工数の見積もりで決まると言っても言い過ぎではないでしょう.多すぎれば生産性が低くなるし,少なすぎるとテストができずに品質が悪くなる.最高の生産性と最高の品質を両立させるには工数の見積もりがモノを言います.もっと言うと,プログラマの価値や,人生そのものがかかっている重要なことであるとも言えると思います.
|
|
|
●●みんな,がんばりすぎ. |
|
|
がんばってはいけないと言っているのではなくて,できるだけ普通にやって,普通にやった場合の効率を知るべきだし,周りの人にもその普通にやったときの効率を知らせるべきだと言いたいのです.
がんばってやってしまうと,そのがんばったときの効率が「普通」になってしまい,その効率で工数の計算をしてしまうことになってしまう.がんばることが普通になってしまい,普通にやるとサボっていることになってしまうからです.ようするに「前回,がんばってこれだけできたのだから,次回も同じようにがんばればできるだろう」という思考になってしまうようです.そうではなくて,やはり「普通の効率を算出すべきだし,普通の工数で見積もるべき」です.がんばって作業をしてしまってバタバタした状態の中でぎりぎりに完成したモノと,普通に作業をして余裕を持って完成したモノの品質の違いは明らかでしょうし,できることならお客さんにもそのことを伝えて,納期の交渉もスムーズに行いたいものです.
「いやいや,お客さんへの納期がすべてにおいて最優先なのですよ」という意見もあるでしょう.そういう考え方のお客さんには,そういう考え方の開発者のところに行ってもらうとして,自分たちの仕事のスタイルと,製品の品質へのこだわりと,最終的には大きな目で見たメリットを追求することが「本当のお客さん」への貢献につながると筆者は思います.そうすることがきっと「ポジティブなループ」になり,まわりまわって,自分たちや,自分の周りの人たちにも貢献できることになるのではないでしょうか.
サービス残業をしていませんか?会社のためと思って仕事をしていませんか?それが本当に会社のためになる作業なのですか?自分は犠牲になっても会社に貢献できれば良いのですか?何かが違うと思いませんか?そもそも会社という組織は,お客さんにも,投資家にも,そして会社員にも,その会社に関わっているすべての人にメリットが渡ることを目的に組織されたモノではないのでしょうか?
|
|
|
●●最後に |
|
|
具体的なコードの話はほとんど出てきませんでした.具体的なコードの話を期待していた方,ごめんなさい.
次回は「大規模なコードと小規模なコード」について書いてみたいと思います.お楽しみに.
|
|
|
●コラム裏の裏は表 |
|
|
一見,初心者ふうのこんなコードがあったとします.
if ( x > 0 ) a = 1 ;
else if ( x == 0 ) a = 0 ;
else a = -1 ;
|
さて,コーディングレベルが上がってくると
a = ( x >0 ) ? 1 : ( ( x==0 ) ? 0 : -1 ) ;
|
こう書いてみたくなったりしませんか?でも,これって可読性が悪いですよね.パッと見ただけでは何がしたいコードなのか理解できません.さらにレベルが上がってくると
if ( x > 0 ) a = 1 ;
if ( x ==0 ) a = 0 ;
if ( x < 0 ) a = -1 ;
|
こう書いたりするのです.最初のコードとあまり変わりませんが,可読性が良いのでわざとそう書いているのです.else文を使いたくても可読性を優先するところがミソです.初心者ふうのコードを見かけたら,そのコードが本当に初心者の書いたコードなのか,もう一度考えてみることをお勧めします.
|
|