見出し画像

『ソフトウェア作法』の頃 (T1:Pt2:Ch01-3)

『ソフトウェア作法』、①紹介編は書きましたが:
「『ソフトウェア作法』とプログラミングの心(マインド)」(T1:Pt2:Ch01-1)
「『ソフトウェア作法』に見るテストの心(マインド)」(T1:Pt2:Ch01-2)
「自分がこの本を読んでどうだったか」をやっぱり書き残しておきたいなと(´・ω・) いうことで②回想・感想編です。



勉強するなら、よい本を(´・ω・)

特定の言語に依存することのない、プログラミングのよい考え方や取り組み方、プログラムのデザインの仕方、さらには設計者/実装者自身によるテスト(の重要性)テストへのよい取り組み方まで、プログラマー初級から中級へのステップアップに際して多くのものごとを教えてくれた一冊でした。“擦り切れるほど読んだ”トップ3に入る技術書です。

筆者が本書に出逢った経緯は思い出せません……
当時の仕事場のわりと近くに専門書の品ぞろえがいい書店があり、そこで発見したのかも知れません。コンピュータ/ソフトウェア専門誌で紹介されていて興味を持ったのかも知れません。仕事場の同僚/先輩に勧められた可能性は、本書については薄いかな(・ω・`)


構造を創る

(独立した)ひとまとまりの“仕事”

関数/サブルーチンの作り方は覚えても、「粒度感はどのくらいが適当なのか?」にはけっこう悩んだりします。当時、「関数の長さは25行とか60行とかまでを目安にするのがよい」なんてことが、仕事場でわりと真剣に議論されたりしていました。

これらの数字にはそれなりの由来と意味があるんですが、長さを目安にするのは筋が悪いことはちょっと考えれば判ります(だから議論もすぐ立ち消える)。本書はそういう数値の話は一切なしに、「関数やサブルーチンを括り出す判断基準」を明快に論じています。
自分はというと、悩んだり迷ったりしながら考えていた“粒度の在り方”の根拠を、本書が裏づけてくれた……という感じだったかな。

関数やサブルーチンとして括り出され、名前をつけられた「独立した仕事」は、名前で呼び、利用することができるようになります。抽象化の第一歩・手続き抽象です。

「誰かが知っていればよいこと」を一箇所に閉じ込める

データに対する操作(生成、挿入、削除、読み書き、等)をインターフェイスにして、「データの構造の実現や操作の詳細はデータを操作するインターフェイスの向こう側に隠す、“閉じ込める”」という、データ抽象という考え方もごく自然に紹介されており、大いに影響を受けました。

プログラムがちょっと込み入った構造のデータを必要とする時、そのデータの構造が“丸見え”のままプログラムを書くこともできますが、そうすると:

  • データを操作するコードがプログラムのあちこちに散在する。同じようなコードがあちこちに出てくる。(⇒データ構造回りを修正するのが面倒≒誤りも起こりやすい)

  • データを操作するコードとビジネスロジックが混在して、ビジネスロジックが見えにくくなる

ということが起こって、最初に書いている時は気にならなくても先々トラブる種になりがちです。
データの構造やその操作の詳細はデータ自身が知っていればよいし(①)、利用する側は利用の仕方だけ知っていればよい(②)。利用側には②だけ知らせて、①はデータ側に隠しておく。
これがデータ抽象で、これにより、データ構造回りに修正が入っても影響を受ける箇所を局所化できます。
(オブジェクト指向言語には最初から具わっている仕組みです)

「最初は実装が容易なデータ構造を用いてプログラムの動作を実証し、のちに速度や拡張性の必要に応じて改良する」というアプローチが取りやすいメリットもあり、デザインに柔軟性というかある種の余裕も与えてくれる考え方です。本書にはこのメリットを活かした事例も載っています。
(この節の見出し「「誰かが知っていればよいこと」を一箇所に閉じ込める」は、手続き抽象にも言えることですね)

「設計と実装は表裏一体」だとも思う

「(設計もそこそこに)コードを書いてみる、動かしてみる」のは、筆者も好きでした。何といっても、机上で頭の中であれこれ考えをひねり回しているだけよりずっと楽しい。

それが許される規模の案件が多かったという背景はありますが、これには「設計と実装は表裏一体」という、自分のわりと根っこ近くにある思いがあります。

ソフトウェアのデザインは文字通り「絵に描いた餅」。実装して(動かして)初めて行ける/行けない・よい/悪いが判定できるわけです。動かしてみてようやく問題点や弱点が見えてくることもしばしば。
「気になる部分」は設計上もネックになる箇所だったりもするので、「手戻り」を少なく抑えるためにも早いうちに動かしてみることができるとよい。

だから「(設計もそこそこに)コードを書く」のは“アリ”だと思いましたし、思っています。
ただそこで気にかけたいのは、「全体への見通しを持てているかどうか」です。

トップダウン設計と段階的詳細化

「まず書いてみる」が健全(?)にできるためには、それが全体の構造のどこにどんな風に位置づけられるのかの見通しは必要です。独立した仕事として考えられるものなのか、大きな仕事の一部で、データ構造や変数を共有してもかまわないものなのか、どんな仕事からも呼び出せる汎用的な仕事なのか。

それなしに「闇雲に思いついたことを書いてみる」のは、“イケてる”コードが書けたとしても、全体の設計に組み込む時に考え直したり書き直したりする手間がかかってしまう。その過程で誤り(エラー)がコードを台無しにするリスクもある。
また、「実装しながら設計を考える」「コードを書いていたらいつの間にか全体の設計ができていた」などという都合のよいことはなかなか起こりません。

というわけで、私見ですが、全体像のアウトラインを描いてから各部分の詳細化を図るトップダウン設計は、「まず書いてみる、動かしてみる」やり方に優しいデザインの進め方でもあります。なにしろスカスカの側だけしかない状態でも“動かす”ことはできる(ものによります)。詳細化に当たっても、他の部分との整合性を意識しながら書き進めることができます。

テストレベルの意味

(この節はISTQB的知見を踏まえて書いていますが)
……と見てくると、設計者が行なうテストにも、いくつか異なる視点があることが判ります。

  • ソフトウェア/プログラムの構造を支える構成要素のテスト。構成要素の外部インターフェイスと内部ロジックの検証/妥当性確認(⇒主に単体テスト(コンポーネントテスト))

  • 構成要素を適宜用いて実現するアプリケーションロジックの検証/妥当性確認(⇒単体テスト~統合テスト)

ISTQBシラバスはふわっっっとした表現でふわっっっとしたことしか言っていませんが、こういう見方をしてみると、各テストレベルのテストの目的、方針、実施事項などがイメージしやすくなるのではないでしょうか。


RatFor -- “言語を創る”

本書の設計例・実装例は、RatForという言語で書かれています。手続き型の言語で、今のプログラマー/ソフトウェア技術者にとってはややなじみが薄い(または“古臭く”感じる)かも知れませんが、制御構文(Cっぽい)も含めた言語の説明もあり、コードを読むのに苦労はしないでしょう。
この言語とその発想にもしびれました。

RatForは"Rational Fortran"の略です。
第一世代プログラミング言語であるFortran、書式に制約があり(一行の長さが固定、特定のカラムに意味があるなど)、分割コンパイルが苦手で、スタックもなく、制御構文も貧弱なFortranに、近代的な制御構文を導入しフリーフォームで書けるようにした「合理的なFortran」。

それも、コンパイラを新たに書いたわけではなく、プリプロセッサとして実装している。RatForで書いたコードからいったんFortranのコードを出力、そのままFortranコンパイラを通せば実行形が手に入るという仕組み。(本書中にRatForプリプロセッサの設計・実装例が載っている)

そういう言語を創って使うことにした理由は、本書執筆時のメジャーなコンピュータ環境で、機種を問わず利用できる見込みが一番高く、移植性が一番高いのがFortranだったからだそうです。でもFortranをそのまま使うのはちょっとアレだと。
(筆者が本書を読んだ時代なら、おそらくCが採用されていたでしょう。今ならJavaが最有力候補かな? インタープリターもよしなら、Ruby, Perl, Pythonなどでしょうか)

そういう発想――ターゲット言語に一枚皮をかぶせて記述力を高めた“別の言語”にする――という発想にも揺さぶられましたが、「言語を創る」ということ自体に大いに刺激されました。

目的にかなう言語がないとか、利用可能な言語では力不足とかいう時に、既存の言語を“騙しだまし”使うのでなく、目的に見合う言語を創ってしまおう という発想。
問題をやっつける“やり方”はたったひと通りではなく、色んなアプローチがあるし、色んなやり方をしていい。
ちなみに著者の一人カーニハンは、本書執筆と同時期に、“小さな言語”である初代Awkの開発に携わっています(後に機能を強化し、汎用スクリプト言語に育ちます)。

もともと言語というものには興味津々で、ひょんなことからプログラミングということをするようになってプログラミング言語なるものにも大きな関心を持ってはおりましたが、その興味関心が一層加速したきっかけだったかも知れません。あ、そういうの(も)アリなんだと。


“プログラミングの友”3点セット(仮)

いずれも、本書からもらったか、少なくとも本書を機に自分の慣行になった考え方、プラクティスです(だったと思います)。

電話テスト

①紹介編で割愛したものですが、

一般に、怪しいと思ったときは「電話テスト」というのをやってみるとよい。論理式を声に出して読みあげたのを耳で聞いて理解できたら、その論理式はまずわかりやすいといってよい。そうでなかったら書き換えをすべきだ。

([1] p.89)

今読み返すと、「if文の判定について、ANDやORで複合した論理式を書くこともできるが、判りやすさを優先した……」という文脈で登場します。

筆者は何を読み違えたか、「設計上の難所、ロジックの組み立てで判りづらい箇所について、読み上げて人に聞いてもらう」と拡大解釈して、チームのメンバーや同僚にしょっちゅう“読み聞かせ”をしていました。迷惑をかけた方々には今更すぎるけどお詫びと御礼申し上げます。

「設計やコードを読み上げて人に聞かせる」というのは実に効きます。副次効果として?、時には読み上げている最中に自分で誤りに気づいたりもします(従って、レビューミーティングを開いてドキュメントを書いた当人に読み上げてもらうのはとても効果的)。

(なお、「(判定箇所の条件式は)判りやすさを優先する」も、理にかなった指針ですね)

擬似コード

擬似コード(でプログラムのアウトラインやロジックのデザインを書く)というアイデアも、本書を読む前から知っていたかも知れませんが、自分の“常用ツール”になったのは本書を読んでからだと思います。

考えたプログラムの挙動をどう表すか? は太古の昔からの課題です。フローチャートは、悪くはないのだけどよくない場合も多い。
自分の身の回りにはソフトウェア設計を視覚化するダイアグラムが浸透していなかったという僻地性もありました。もちろん、UMLが生まれるよりずっと昔の話。

自分なりに勉強して、HIPOというのが有望に思えましたが、そのHIPOを「楽に描く」手段がなかった。
当時は「デザインを視覚化する」手段自体が貧弱でした。ダイアグラムエディターもなくぱわぽもエクセルもなく、手書きが一番マシでかえって“楽”だけどそれをスキャンするデバイスもない。キャラクターでそれらしい「図」を(今でいう“アスキーアート”の要領で)書くなど涙ぐましい努力をしてみたり。

という環境/制約の下では、「プログラムのロジックを擬似コードで表す」というのは“最善の解”に思えました。テキストエディターあれば書けるし記述の粒度を調整できるし、コメントも書き添えられるし。机上でいけそうに思えたら、それを実際のコードに書き換えて動かしてみるのも容易でしたし。

“早期テスト”

ISTQBの「テストの原則」にあるのとは違い、「設計と(コーディングと)テストの設計(~実行)を並行して進める」といった意味です。当然、このやり方が円滑に進むには、トップダウンで全体像が見えていることが前提になります。

筆者が携わってきた案件は主に“セルフ開発”(という言葉は当時はありませんでしたが)だったのでこれをやりやすい状況でした。
実践してみたらとても具合がよいものでした。

モジュール(関数など)の外部インターフェイスが決められれば、デザインの途上でも“テスト”ができる。インターフェイスパラメータのエラーチェックを先に書けば、呼び出しまでのテストはできる。“側”が“動く”ことが確認できたら、後は各モジュールの中味を詰めていけばいい。

以降、このやり方は自分の設計・実装の進め方の基本になりました。(筆者が「ソフトウェアをテストする」ということをもっと勉強し、実践するのは、本書を読んでからもう少し後のことになりますが)
(ちなみに、「早期にテストを考える」は、ワインバーグ『要求仕様の探検学』でも取り上げられている考え方です)


むすび

当時の仕事場には、新人プログラマーに1対1で中堅~ベテランのプログラマーを指導役につける“コーチャー制度”という仕組みがありました。

最初にコーチャーを務めた時だったか、なぜかふと、“修行”が明ける際に“餞(はなむけ)の品”を贈ろうと思い立ちました。

各自のその先のソフトウェア技術者人生に役立ちそうなものをと考えたので、相手に応じて餞は変わりましたが、本書は常にその中に含めていました。
(本稿を書き上げる頃にようやく思い出しました。そんなこともしていたっけな……)


文献・書誌情報

  • [1] Brian W.カーニハン, P.J.Plauger (木村泉・訳) 『ソフトウェア作法』 (原著1976, 日本語訳1981) 共立出版

    • 原著 (日本語訳の扉記載の情報に基づく)

    • Software Tools

    • Brian W. Kernighan, P. J. Plauger

    • 1976初版 (Addison-Wesley)


(2024-02-09 R001)

この記事が気に入ったらサポートをしてみませんか?