Tatehitoの技術メモ

ソフトウェアエンジニアです。いろいろ書きます。

感想『オブジェクト指向設計実践ガイド』

既存コードを修正するのと、ゼロからコードを組み上げるのは難易度が全然違います。既存コードの修正は、既存のアーキテクチャに則ってコーディングするのが基本です。つまり「既存コードを真似して書く」ことができます。

一方、ゼロから組むとなると、自分でアーキテクチャ設計をする必要があるわけで、これが難しい。難しいというのは、質の高い設計、変更に強い設計をするのが難しい、という意味です。テキトーな設計で良ければ難しくありません。

この話を聞いて、「まあゼロからつくるほうが難しいよね」と誰でも想像はつくと思いますが、実際にゼロからつくってみると、それをめちゃくちゃ実感します。僕の場合、Railsの勉強のためにつくった「ポケモンしりとり」は、問題なく動いてますが、コードはイケてないです😢

blog.tatehitolog.com

個人開発が初めてだったこともあり、「動くものをリリースする」ことを最大の目標としていて、あまりコードの質を意識していなかった......という言い訳があるにはあるんですが、それにしても、いま読むとまあヒドイ。どうヒドイかというと、全然オブジェクト指向プログラミングを活かした設計になっていないところがヒドイ。

ということで、最近はオブジェクト指向関連の書籍を中心に読んでいます。今回読んだのは『オブジェクト指向設計実践ガイド』です。Rubyのサンプルコードが豊富な、オブジェクト指向の実践本です。

翻訳文が読みづらかったけど何度も読むうちに...。

はじめて読んだときは、訳書特有の独特な言い回しもあって、正直内容が頭に入ってきませんでした。著者の頭の中の言葉をわ~っと書きだしたような文章で、個人的には訳書の中でもかなり読みづらい部類に入ります。慣れていない人は最後まで読み切る前にくじけてしまうかもしれません。

初見では5割くらいしか理解できていなかったというのが正直なところですが、オブジェクト指向に関する知見を深めてから読み返したり、実務でクソコードと向き合った後に読み返したりとしているうちに、今まで読みづらいと思っていた文章がすべて腑に落ちた瞬間があって、それからは手放せない良本になりました。

サンプルコードが豊富な実践本

設計とは「アプリケーションの可変性を保つために技巧を凝らすこと」であり、なぜ設計が必要かというと、変更に強いコードを書くためです。極端な話、変更されないアプリケーションは雑にコーディングしても問題ないです。趣味で規模の小さいアプリケーションをちょちょっと個人開発するくらいなら、設計せずに一気にコーディングしたほうが、むしろいいかもしれません。

「じゃあ変更に強いコードを書くための設計ってどうやってやんの~?」という質問に対して、実例をあげて答えてくれるのが本書です。サンプルコードが豊富で、イケてないコードがオブジェクト指向のテクニックを使ってイケてるコードに変わっていく様を見せてくれるので、イケてるコード・イケてないコードの違いがよく分かります。

注意点としては、Rubyの文法に関する説明はないので、Rubyの知識が浅い人や、オブジェクト指向プログラミングに全く触れたことがない人には、ハードルが高い本だと思います。

変更されたらどうなるか?を想像する

それから、本書の内容とは直接関係ない感想になりますが、

アンチパターンやベストプラクティスを知識として知っておくのも大事だけど、「この書き方だと仕様変更になったときに直すの大変じゃね?」という感覚が持てるかどうかが大事だと思いました。

もし類似クラスが増えたら?変数の持つ意味が変わったら?そうなったら、このコードは再利用できるだろうか?修正個所は何か所になるだろうか?そういった感覚があるからこそ、本書で紹介されているパターンやテクニックを適用できるのだと思います。

実務と情報のインプットを繰り返して、知識に頼らない応用力もつけていきたいところ!

おわりに

さいごに、本書を通して学んだテクニック的なメモを残しておきます。※本書の引用でなく、僕なりにまとめた文章なのであしからず。

・複数の責任(処理)を持つオブジェクトは簡単に再利用できなくなってしまうため、クラスもメソッドも単一責任にするのが基本。単一責任かを確かめるには、そのクラスを一言で説明してみる(説明できたら単一責任)。

・依存は少ないに越したことはないが、ゼロにすることはできない。不必要な依存は排除し、依存は隔離(一か所にまとめる)する。

・依存を隔離する手段として、ラッパークラス・ラッパーメソッドがある。依存箇所をラッパーメソッドで包み、そのラッパーメソッドを参照するようにしてやれば、依存先のクラスの仕様が変わったとしても、依存箇所はその一か所で済む。外部オブジェクトへの依存だけでなく、インスタンス変数など様々な個所から参照されうるものは、ラッパーメソッドで包んでおけば変更に強くなる。

・AがBに依存するか、BがAに依存するか、コントロールできる場合は、変更されづらく、依存されている数が少ない方のオブジェクトに依存させる。依存方向を意識する。

・パブリックインターフェースとメッセージが、アプリケーションを構成する。シーケンス図を用いてオブジェクト間でやり取りされるメッセージを図示することで、必要なオブジェクトを洗い出すことができる。

・ダックタイピングを使いこなすことで、よりインターフェースを柔軟にでき、クラスへの依存を排除できる。ダックタイピングは具象的な存在でないため、理解しづらいという難点はある。テストコードをしっかり書いて明文化すること。他人が書いたダックタイプを破壊しないように、ダックタイピングの概念を理解しておくこと。

・継承、モジュールのインクルード、コンポジションのメリットとコストを理解したうえで、適切に使い分ける。

関連記事

blog.tatehitolog.com