再読『ベタープログラマ』

はいどーもこんにちはニートです。
『ベタープログラマ』を再読したので、本日はその感想記事を書いていきたいと思います。
ちなみに前回は「現状の僕には関係のない話ばかりなので、いずれチーム開発するときが来たら再読したいなあと思いました」って感想を書いてましたよ。

結びから

いきなりですが、まずは本書の結びから少し引用します。
「数か月後にこの本を読み直してください。(中略)そして、あなたの視点、経験、理解がどのように変化したかを認識してください。あなたが勤勉で、よく考えて実践することに集中したなら、自分の成長に驚くことでしょう」
まさに今の僕は「数か月後にこの本を読み直し」た人物です(前回読んでから半年くらい経ってます)。
僕は果たして「自分の成長に驚く」ことができるのでしょーか。
というわけで各項目を細かく見ていきます。

テストはやはり大切

他の多くの場所でも書かれていることですが、やはりテストの大切さはこの本でも強調されています。
「適切なリファクタリングは修練を必要としますが、問題となるコードを網羅している優れた単体テストが一式あればリファクタリングは容易です。単体テストは、どのような変更でも振る舞いを変えていないことを証明するのに役立ちます」
これはまさにその通りだと思います。
僕も最近は積極的にテストを書いていて、コードの挙動を変えたり、リファクタリングする際に役立ちました。

コードの保守期間

みなさんは自分のコードをどの程度の期間保守していますか?
僕はツクールMV用プラグインのコードはちょいちょい保守していますが、そんなに真面目にはやっていませんw
恐らく仕事でコードの保守をしている方は、僕よりは真面目に保守のことを考えている方も多いんじゃないかなあと思っています。
しかし一方で
「自分達のごみの中で悪戦苦闘するよりは、新たな職場に移って誰か他の人のごみの中で悪戦苦闘する方を選びます」
「他人のできの悪いコードについて不平をいうのは楽しいでしょう。しかし、私達は自分のコードがどれだけ悪いかを簡単に忘れます」
みたいな人もいるようです。
新しいプロジェクトに行くのは楽しいことだと思いますし、書いてる最中は自分のコードの汚さはなかなか気が付きにくいので、ある程度は仕方ないんですかねえ……。
気をつけたいところです。

バグの避け方

プログラムを作っていると、やっぱりバグが出てきます。
いくらテストを作っていても、すり抜けちゃうことありますもんね。
そんなバグを避けるための助言が本書にも書かれています。
それは「賢すぎるコード(たいていは複雑なコード)を書かないこと」という単純なものです。
これは「人が理解できるコードを書く」と言い換えることもできます。
あんまり上手い例が思い浮かばないのですが、例えばfor文なら多くの人が読めると思いますが、同じことをLINQで書くと読めない人もいるかもしれません(さすがにこれはプロなら勉強しろというレベルな気もしますがw)。
コードはコンピューターが読むために書くのではなく、人が理解できるように書くことを意識していきたいと思いますよ。

クラスが協調するオブジェクト

本書によれば「クラスが協調するオブジェクトは、コンストラクタのパラメータとして渡されるべき」とのことです。
これはいわゆる依存性の注入のことかなと思うのですが、協調するオブジェクトをインターフェイス型のパラメータとして受け取ると、クラスの内部で特定のクラスに結びつく、ということがなくなります。
ただコンストラクタでパラメーターを受け取らなくても、例えばZenjectなどの依存性の注入のためのフレームワークを使用してもよいと思います(規模によって変えるのがいいんだと思います)。

循環した依存

循環参照は止めたほうがいい、と各所で言われていますよね。
本書でも「一つのオブジェクトの変更は、他のオブジェクトの変更を必要とし」「保守するのが困難」になるから循環参照は止めたほうがいいと書かれています。
例えば以下のような一見すると単純なモデルも、循環参照しているので実はめちゃくちゃ複雑なモデルとなっています。

A←→B
A←→C
A←→D

BはAを知っており、AはCを知っているので、BはCを知っていることにもなりますね。

これが

A→B
A→C
A→D

というモデルなら、AはBを知っているがBはAを知らないので、BがCを知ることもないモデルとなって非常に理解しやすくなります。
僕もクラスを設計するときに気をつけたいと思いますよ。

間接データ

インターフェイスを上手に挟むとコードの柔軟性が上がりますが、闇雲に使うとコードが複雑になるばかりです。
特に僕みたいに最近「インターフェイス! DI! サイコー!」なんて経験をした人はその傾向が強いような気がしますw
それを戒めるためにも、本書から以下の一文を引用しておきます。
「単純な設計は、不必要な継承、ポリモフィズム、動的結合を避けます」
僕もなるべく単純な設計を意識したいと思いますよ。

学びについて

本書の中で中国のことわざが紹介されていました。
それはこんなものです。
「学びは上流へと漕ぐようなものだ。前進しなければ後退するだけである」
僕はここ一年ほど学習を継続してきましたが、かんばしい成果がなかなか上がらず、正直に言うと学習意欲が低下気味でした。
ですが「前進しなければ後退するだけ」という言葉を胸に刻み、少しずつでも学習を続けようと思いますよ。
まあ、結果が出ていないのは、お金に繋がるようなことをあまりやっていないのも原因な気がしますが……。

答えることができない質問

僕が素人ながらにブログでアレコレと技術的な話題を扱っているのは、自信の知識を整理するためという側面もあります。
つまり記事を書くことによって、正確には理解できていない箇所をあぶり出しているわけです。
不明な箇所は重点的に調べ、調べた結果も記事に盛り込むのです。
それでもなおわからない箇所については「わからないので近い内に調べておきます」と書いたり「誰か教えてたもれ」と書いたりしておくと親切な誰かが教えてくれるわけですねw

問題を解決するツール

問題を解決するツールについて、本書では以下のように書かれています。
「問題を解決するために、一つのツールあるいは一つの方法を常に頼りにするのは危険です」
例えばあなたがRPGツクールMVを使うのに慣れているとします。
そこでRPGツクールMVを使ってノベルゲームを作ろうとします。
恐らくは作成可能でしょう。
ですが、もっとよいツールがすでに存在しているかもしれません(たぶん存在します)。
今回ならノベルゲーム専用のツールを探し、その探し当てたツールの使用を検討する価値は十分にあるでしょう。

やらなければならないこと

本書では一貫してリファクタリングやテストの重要性が説かれています。
ですがそれでもなお「リファクタリングや単体テストをする必要があるかをよく考えてみてください」とも警告しています。
もちろんリファクタリングをしてコードを読みやすくしたり、単体テストを作成してコードが正常に動くことを保証するのは大切です。
ですが「小さなプロトタイプに取り組んでいたり、捨てるつもりのコードで機能的な設計の可能性を探求」している場合はリファクタリングしたり、テストを作成する必要はないかもしれません。
実際、テストが必要にならないくらい簡単なスクリプトを個人的に作成し、使用する場合、やっぱりテストは不要な気がします。
「正しいやり方」にこだわらず、本当に必要なのかどうかを一度考えてみるのも重要なのだなあと思いました。

複数の選択肢がある場合

何かのプログラムの作成を決めて、設計の案が複数出たとします。
そのとき、どの設計が最善なのかを頭の中で考え、何時間も悩むことは時間の無駄かもしれません。
ではどうすればよいかと言えば、本書では「捨てるプロトタイプ」の作成が勧められています。
実際に作ってみることで見えるものもある、ということでしょうかね。

依頼者に製品を見せるタイミング

かつて僕はツクールMVのプラグインの制作依頼が来たとき、完全に完成してから依頼者に「できましたよ」とプラグインを見せていました。
これは「完成品以外を見せるのは失礼だ」と以前は考えていたからです。
というのも、昔僕が慣れ親しんでいた文化にこのような考えが蔓延していまして、違う文化であるプログラミングに対しても適用していたのですね。
ですがこの方法だと、完成品を提出したときに「いや、なんかここ、思ったのと違うんだけど」と言われたり、「あ、この機能よく考えたら使わなかった……」とか言われたりするんですねw
なので、今の僕はできるだけ早い段階で依頼者にプロトタイプを提出しています。
たとえ完全に動くものでなくても、機能のすり合わせや、要件の整理程度ができるならば、それは依頼者に提出する価値があると今の僕は考えていますよ。
本書でも似たようなことがもっとシンプルにまとめて書かれています。

テストは完了を示す

作ったものがいつ「完了」するのかを明確に定義できないと、いつまで作業をすればいいのかわかりませんよね。
これは僕も経験があって困ったことがありますw
本書によれば「コーディングのタスクでは、明確なテスト一式を作成することで、「完了」をはっきりと示すこと」ができるそうです。
確かに先にテストを作成するスタイルならば、初めは全てのテストが失敗するはずですから、全てのテストが通るようになったならタスクの完了を意味しますよね。
これは僕も真似したいなあと思いつつ、なかなか先にテストを書くというスタイルが自分の中に根付かないのが難儀ではあります。

コメントを増やすと

ツクールMVのコアスクリプトには、コードに対するコメントがほとんどありません。
それでも理解に詰まる箇所の少ないコードとなっています。
「これこそがまさに優れたコードだ!」と僕は思っていて、変数名やメソッド名、クラスやメソッドを分割する大きさなんかでよく参考にしています(マジックナンバーが多いのが玉に瑕ですが)。
本書でもコメントについて触れられていて、「コメントを増やしたからといって、必ずしもコードがよくなるわけではありません。意図を明確に伝えているコードは、余分なコメントを必要としません」と言っています。
僕もこれには同意なのですが、チームとして活動する場合、それなりにコメントはあった方がよいのかなあ、なんて思います。
特に日本人の場合、クラス名やメソッド名等は普通英語で名付けられるので、これだけで読むのが負担です。
なので、各クラス・メソッド等の単位において、サマリでサラッと説明を書いておくのが親切なんじゃないかなあと思いました。
以上のことを踏まえ、今の僕は「メソッド名を見れば何をしているかわかる!」と主張してコメントを一切書かないのではなく、機能を軽くまとめたコメントを必ず添えるコーディングスタイルにしていますよ。

顧客との会話

当然といえば当然のことですが、プログラマが使う専門用語を顧客が理解していると期待するべきではありません。
もちろん正確な説明のためや、説明の簡略化のために専門用語を使いたい気持ちはわかるのですが、何も伝わらないよりは噛み砕いた説明の方が百倍マシです。
というわけで、僕も依頼者に何かを説明するときは、なるべく噛み砕いた説明をするようにしています。
意思疎通ができないで、お互いよくわからないままプログラムを作って、結果それが無駄骨だったとか本当に笑えませんからね……。

マニフェスト

ソフトウェア開発の世界にもマニフェストがあるらしいです。
有名なものとして、以下のものが紹介されていました。

・アジャイルマニフェスト
・クラフトマンシップマニフェスト
・GNUマニフェスト
・リファクタリングマニフェスト
・ハッカーマニフェスト

どれも全く読んだことがないので、そのうち読んでみたいなあと思いましたよ。

プログラマの態度

本書によれば「ひどいプログラマと優れたプログラマを区別しているものは、態度」らしいです。
態度こそが「単なる適当なプログラマと並外れたプログラマを区別する」らしいのです。
前回この項目を読んだときは言っている意味がよくわからなかったのですが、今なら言わんとしていることが理解できます。
例えば僕が様々なスキルを知識として持っていて、実践できる力があったとしても、ひどい態度のプログラマであれば「チームの誰もテストを作っていないから、俺も作らない」と考えたり、「俺が読めればそれでいいから、読みやすい書き方なぞクソくらえ。他のやつのことなど知るか。俺は読める」と考えたりするかもしれません。
もちろん、テストの作り方を知らなかったり(あるいはテストできるようなコードが書けなかったり)、綺麗なコードをそもそも書ける技量がなかったりするのも問題ですが、技量があっても態度がひどければ全て何の役にも立ちません。
以上のことを、本書では端的に「あなたがどれだけ技術的に有能なプログラマであるかは問題ではありません」と言っています。
僕はまだまだ「技量のあるプログラマ」からは程遠いですが、せめて態度くらいは倫理的でありたいなと思いましたよ。

終わりに

本日は『ベタープログラマ』の再読感想記事を書きました。
最後に、最初に紹介した結びの文章を再び引用します。

「数か月後にこの本を読み直してください。(中略)そして、あなたの視点、経験、理解がどのように変化したかを認識してください。あなたが勤勉で、よく考えて実践することに集中したなら、自分の成長に驚くことでしょう」

前回読んだときは正直チンプンカンプンな部分が多かったのですが、『プリンシプル オブ プログラミング』同様、理解できる項目が格段に増えていて嬉しかったですね。
僕の学習方法が効率的かどうかはわからないけれど、少なくとも間違ってはなかったのだなあと確信できました(昔から時間ばかりかけて、効率自体は悪いことが多いのでw)。
再読してよかったです。

ほなそんな感じでまた。
お仕事も募集中です。

フォローする