ごきげんよう、あすみです! これはNE Advent Calendar 2022の23日目の記事です!
今日でちょうどあすみウィークの中日。もう3日目かー 前回のアドベントカレンダーはこの日で終わりだったわけですが、あの頃と比較すると大分diffがあります。
まず、筆の進みが格段に速いです。去年より。 なぜそうなったのかと考えると、今年1年で「人に見せるための記事をアウトプットする」というのに慣れたからと思います。 ・・・え?ブログのエントリー少ないじゃんって??違うんです!!社内記事サイトで割とゴリゴリかいてます!!!週間アウトプットランキング1位の常習犯です!!
と、言い訳したものの、1ヶ月を振り返る記事を毎月ブログに書こうーと思って6月で止まってるので、反省しなきゃですね。 年末に、今年分出します!!必ず!!きっと!!・・多分・・・
さて、今日は「良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方」という本を紹介したいと思います。 400ページの本ですが、中身に書いてあるのは割と理解しやすい話が多く、2〜3日に分けて数時間読んで読破した気がします。
良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方
どんな本?
この本のスキな部分
staticメソッドが存在するクラスはオブジェクト指向なクラスではない
「第5章 低凝集 -バラバラになったものたち-」の中で、staticメソッドの誤用として、間違ったstaticメソッドの使い方が述べられています。
かつての私は、「これはstaticにしてもいけるからstaticでいいんじゃないの?」と思うことがありました。 あまり、staticメソッドについて特段注意深く考えておらず、寧ろ、「どこからでも呼べて便利じゃん!」とか、極端に言えば「処理中に影響を及ぼしにくくて寧ろ全てがstaticな世界が気持ちいいのでは?」とすら思っていました。
しかし、オブジェクト指向な設計にしたい場合、上記の様な考え方は間違っていたな、と今になって思います。
なぜ使ってはいけないのか?
クラスで、物体(ある特定の責任を持っている)が表現され、プロパティで物体の関心事が管理されている、そしてメソッドで関心事に関する処理を行う、そんなクラスらがやりとりをし合うのがオブジェクト指向、と自分の中で考えているのですが、staticメソッドはこれらの思考に反する物になる可能性が高いです。
<?php class Buttai { private $kanshin1 private $kanshin2 public function process() { // ここからは$kanshin1や$kanshin2に関与できる $this->kanshin1 = ' ... '; $this->kanshin2 = ' ... '; } public static function dokuritsu() { // ここからは$kanshin1や$kanshin2に関与できない // ❌ $this->kanshin1 = ' ... '; // ❌ $this->kanshin2 = ' ... '; } }
上記に示した様に、staticメソッドがついているものはプロパティに関与できません。($this
によるアクセスができないため)
つまり、本当はそのクラスにあるべきメソッドじゃない、ということなのです。
(厳密には、プロパティにアクセスしないようなメソッドがあれば、staticがついていなくても間違った設計、とも言えます。)
他にも様々な理由はあるとは思いますが、この考え方が私の中でしっくりきました。
(この本にこの例が載っていた気がするが、どこに載っていたか忘れた・・・もしかしたら、ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本の方だっけな?)
使って良いタイミング
ただ、「横断的関心事」のようなタイミングではstaticメソッドは適した使い方になる、と書いています。 例えば、ログ出力や、ファクトリなど。
これはアプリケーションのどんな処理でも必要なため、これくらいのレベルになると、パブリックなところに宣言されててもいい→staticでいい、みたいな考え方だそうです。うんうん。なるほど。納得。
値が入ってないことを表現する時に「null」を使うのはやめよう
しかし、防具を装備していない状態をnullで表現している例と同様に、商品名が未設定の状態、商品の配送先が未設定の状態など、主に未設定状態をnullとして実装しているコードが世の中に多くあります。何かを持っていない状態や未設定の状態も、立派な状態なのです。いわば、その状態すら存在していないのがnullなのです。nullは多大な損失を生みかねません。
(9章 設計の健全性を損なうさまざまな悪魔たち)
これには少々衝撃を覚えました。割と無自覚で空のものはnullとしてしまう習慣が自分にもあったので・・・。 ただ、言われてみると、DDDなどを適切に行っていれば、EMPTYであるかないかに関わらず、必然的にバリューオブジェクトを使用して値のやりとりを行うはずなので、確かにそうだなぁと思いました。
コードの中にif($hoge !== null)
の様なコードが書かれおり、見通しが悪いなぁ、と感じたことは今までの経験の中にあるような気がします。
そもそもnullである時は異常事態なので、敢えてハンドリングしない(もちろん最終的にどこかではするのだが、ハッピーパス的な中でするものではないという意味で)という選択肢には納得感を感じました。
「デザインパターン」を紹介する導入がうまい
本の構成として、「このコードにはこんな課題があるよね」→「じゃあこう直そう!」みたいなテイストで良いコード・悪いコードを説明しているのですが、その流れで、自然とデザインパターンの紹介も入っています。いやあこの導入から解決策の提示があまりにもナチュラルでめちゃくちゃわかりやすくて良いじゃん、と感動しました。
エンジニアはじめて、ある程度書ける様になって、ちょっと経つと何かしらのタイミングで耳にするデザインパターンという言葉。 よくわからないから、よし、本を読んでみよう!となるのですが、いまいちピンときませんでした。(私調べ)
今になって思いますが、「デザインパターンの本」とかで読むと、さほど課題感を感じてない状態でハウだけ学びにいく感じになるのでピンとこなかったんだなあと。
それが、この本は「こんな課題があるよね」の部分で「今はこんなコードだけど成長するとこうなってっちゃうね?課題だね?」がわかりやすく書かれており、「やべぇ、このコード書くとやべぇわ、やべぇぞ」ってなったところに「じゃあこんな書き方したら解決するよね?」と提示され「うわああああなるほどこうやって書くのか」と驚いたところで、「これはXXXというデザインパターンです」のように教えてくれます。
なんとわかりやすい説明。感動しました。 そもそも、デザインパターンは、ただ単に名前がついているだけの「良い感じにコードを書く方法」ってだけなので、デザインパターンの本で網羅して学ぶより、「良い感じにコードを書く方法」が網羅的にのってるこの本を読む方が理解の助けになりそうだなといった気持ちです。
ところで、去年のアドベントカレンダーでも似た様な事言っているので、ぜひどうぞ。
まとめ
今日ご紹介した本の中身は、めちゃくちゃよかったうちの本当に一部です。 本の中には網羅的に、そしてわかりやすく「良い感じにコードを書く方法」が記述されています。
今後、私の人生の中でエンジニアほやほやの人がいたとしたら、「リーダブルコード」を一番最初に薦めると思うのですが、その次に薦める本当して、「良いコード・悪いコード」を採用すると思います。 それくらい、自分の中で好きになった本でした。 (私が新卒の頃に欲しかったッ!!!笑)
読書難易度もそんなに高くないので、持ってない人は一度購入してサラッと全部読んじゃうのおすすめです。