オブジェクト指向の考え方 5th Editionを読んだ

新しくオブジェクト指向の本の翻訳本が出るみたい、という情報が流れてきたので購入。

オブジェクト指向の考え方 5th Edition (impress top gear)

オブジェクト指向の考え方 5th Edition (impress top gear)

  • 作者:Matt Weisfeld
  • 発売日: 2020/10/23
  • メディア: 単行本(ソフトカバー)

全体所感とかレベル感とか

読み終わっての全体的な所感としては、「思ったよりサクサクと読める内容だったな」というもの。高度な議論を扱った本なのかな〜って思ってたけど、寧ろ逆で、プログラミングを初めて少し経って「オブジェクト指向ってどんなものなんだろう?」と気になり始めた人などに良いのではないか、と感じた。(何も調べないで買うから!)
実際、こういった話題を扱ったものにしては本書中に具体的なコードが少ないような印象。・・・これはつまり「コードで考える方が自然」でない層への配慮なのではないか、という気がする。
12章、SOLID原則の段に至るまでは「極力、オブジェクト指向とは"現実にある物質(オブジェクト)をモデリングするような考え方"であるかのように扱おうとしている」ような印象すら覚えるほどに、「リアルワールドのモノで喩える」試みが見られた。 *1 そういう点をとっても、「オブジェクト指向ってどんなものなのか」に触れる人に向けた本なのかな〜と感じる所存。

前書きの「対象読者」を確認すると、

  • 本書は、オブジェクト指向プログラミングの概念を広く紹介することを目的としている
  • 本書を学ぶことによって、より高度なトピックについての書籍に進むための基礎が構築できるはずである

と述べられているので、やはり「入り口」的な性格が強いかな?と。

あと、「新しい本な感じがする」っていうのも読み易さに繋がるんじゃないかな〜と何となく。
本文中に「Swift」とかって言葉が出てくると、「あ、結構新しいやつだ」って感じがするw

自分は「オブジェクト指向を初めて知る」という目的だとオブジェクト指向のこころ (SOFTWARE PATTERNS SERIES)が大好きなのだけど、その手前で読んでみても良いかも知れない。(あちらは、デザインパターンにまで突っ込んでいくので)

主張について・特徴的な所

とりわけ「振る舞いと実装の分離 / インターフェイス*2」について強調しているような雰囲気を感じる。
オブジェクト指向プログラミング、つまりオブジェクト同士がメッセージのやり取りを介してつながる・・と言った時に「どのメソッドに、何を渡せば、どんなものが返ってくるのか」という抽象的な情報がインターフェイス。そして「インターフェイスだけに注目しておけばいい」という点が、オブジェクト指向プログラミングを価値のあるものにしているよね!というところか。(もちろん、そこから「カプセル化」の価値が導き出されるし、「ポリモーフィズム」についても同様)。

また、「継承の問題点」や「コンポジションの重要性」について強調しているのが興味深かった。
「Chapter1 オブジェクト指向概念への招待 / 1.1 基本概念」から引用すると、

歴史的には、オブジェクト指向言語は、次のようなものによって定義されてきた。すなわちカプセル化、継承、そしてポリモーフィズムである(これを「古典的」オブジェクト指向と呼ぶ)。 (中略) これらの3つに加えて、著者は、コンポジション(合成)も含めたい。 (P2)

とさえ述べている。

大体は「古典的オブジェクト指向」の3要素で終わってしまうと思うので・・・そこから踏み込んで「継承か、コンポジションか」という議論にまで持っていってるのは個人的には本書で1番のお気に入りポイント。
「やっぱり継承って難しいよね」みたいな話は、特にgolangの人気が出てきてから良く目にするようになっていない?と個人的に思っているのだけど、その「危うさ」と提案としての「コンポジション 正しく使おう」という説明は、良い話。
「Chapter 7 継承とコンポジションをマスターする」や、特にその中の「7.4.1 継承はどのようにカプセル化を損なうか」に詳しい。

扱っている話題の広さ

目次を見ると、扱っている話題の範囲の広さを感じると思う。(公式サイトに載っている)

book.impress.co.jp

「基本的な概念」に始まり、「クラス設計のガイドライン」「フレームワーク」「デザインパターン」「SOLID原則」にまで進む。 (「フレームワーク」の話は、期待しすぎると内容のあっさりさを少し残念に感じるかも知れない。あくまで「再利用性を高めることとオブジェクト指向」という文脈で「フレームワークというアイディアの詳解」という話かな、という感じ) これを250ページちょっとでやる。

オブジェクト指向とはなにか」から「実際の開発の現場にどう影響しているか」みたいな視点でいくと、このくらいまでが守備範囲に含まれてくるのか〜という印象。

「設計のガイドライン」はオブジェクト指向を覚えたての人でも明日から仕事で活かせる感じするし、SOLID原則とか分かるとアーキテクチャっぽい話にもつながっていくし、と。

まとめ

サクサクと読めた!!ので、積ん読にしないでザッと読んだの良かったな。昨日届いた(というか、発売日が2020/10/23でその日に届いた)のを今日読んだ感じ。 出てきくるコードは難しくない(雰囲気で読める)、そもそも少ない、UMLもゴクゴク簡単なクラス図に限定して使われているのでアレルギー少なそう。
文章も平易だったように感じる。

OOPとかに興味持ってきた〜って人にオススメしやすそうな1冊なのかな、って印象!

*1:12章に入った途端に、”オブジェクト指向が人間の考え方に近いというアイデアは、単なるマーケティングである。オブジェクト指向が人間の考え方に近いということはない”というボブおじさんの言葉が紹介されている

*2:書籍中だと「インターフェース」という記述になっていたけど、自分はこっちのほうが慣れているので

SQLパフォーマンス詳解を読んだ

仕事で回ってきたタスクで「はぁ〜〜SQL真面目にわからないとだな〜〜」という熱が高まったので、積ん読の順位を入れ替えて読んだ。

を見て f:id:o0h:20201013031330p:plain ってなってたやつです。

4月か、もうずっと前な感じあるぅ。

結論としてめちゃくちゃおもしろかったな、ずっと雰囲気でやっていたインデックスの管理について、雰囲気をつかめたような気がする・・・

「カーディナリティが低いカラムにインデックス張っても意味ないよ」みたいな話とか、理屈で掴めたのがめっちゃ良い。目が覚めるような感覚を覚える。
また、「もしかしたらインデックスヒントやったらワンチャン・・?」みたいなノリで試して→「やっぱ駄目ですよね!アハ!!」とかいう戯れをこれまでに何度も繰り返してきたのについては、少し勘所を掴めそうな気がする。(これはMySQL8以降で変わる部分もありそう、下位バージョンにおいては、機械がよしなにやってくれなそうな部分〜を人力で支援するぞ!!という機会がありそう。みたいなイメージ)

もっと初歩的なことでいうと、「複合インデックス作る時は順序が大事だよ」とか、そういう部分まで含めて、あ〜なるほど〜〜〜って感じに。

いつも技術書等を読む時は、「おっ!」と思った部分は原文を抜き出して自分の感想を添える!という形にしているのだけど、この本は抜き出しが多すぎて比率的に引用って呼べる範囲を超えてそうだな・・・・・という感じすら覚える。

カバーリングインデックスの話も良かったなぁ。。


以下、読書メモ(の一部!!

  • 検索ツリー
    • ルートノード > ブランチノード > リーフノード
    • リーフノードは、ノード同士を双方向連結リストで相互参照している
    • 「リーフ」が、実際のテーブルの行データ情報(=ROWID)を持っている場所
    • 実際にテーブルのデータにアクセスするまでに、ツリーを走査し→リーフノードを手繰り→テーブルからデータを取る、という流れになる
      • この時に、「ツリーだけで済む」ようであれば、極めて低コストで済む。(リーフノードから先については、コストが嵩みやすい)
      • これは「ツリーの深さは増加しにくい」という性質のために、「ツリーだけなら走査しても試行回数がたかが知れている(数回レベル)」というもの
      • 逆に、「ひとつのリーフノードだけでも、数百のエントリを保持していることがある」(P6)
  • カバーリングインデックス
    • where/order/select等、「使う必要がある列(の値)」が全てインデックス上に含まれている場合、「インデックスの表」に載っているデータだけを使って「実際のテーブルのデータ」にアクセスしないで処理を完結させる
  • セカンダリインデックス、クラスタ化インデックスあたりの話
    • セカンダリインデックス = 主キーでないインデックス
    • 主キーはBツリーインデックス、索引構成表、クラスタ化インデックス。ROWIDに直接紐づく
    • セカンダリインデックスは、クラスタ化インデックスに保存された”元のデータ”を経由して、ヒープテーブルにアクセスする
    • 「物理的なポインタ(=ROWID)」をもたず、論理キーを扱う
      • クラスタインデックスのキーの値だけを保持
      • これを「クラスタリングキー」といい、多くの場合は索引構成表のプライマリーキーとなる • それによって、インデックスの順序を入れ替えることが可能になっている
    • 索引構成表を使うと、ROWIDを用いてヒープテーブルにアクセスができるため、テーブルアクセスのコストが低い
    • セカンダリインデックスを利用してテーブルにアクセスすると、まずセカンダリインデックスで検索し(INDEX RANGE SCAN)→クラスタインデックスを検索する(INDEX UNIQUE SCAN)という風に、2つのインデックスを検索することになる。
  • numericな値
    • WHERE numeric_string = 42はインデックスが効かないが WHERE numeric_number = ’42’はインデックスが効く
    • これは「文字列を数値にキャストする」か「数値を文字列にキャストするか」の違いで、前者については、例えば '042' '00042' といった値も数値にしたら42ではあるが、インデックスが作られているのはあくまで0042 といった値に対してなので、つまり「対応するインデックスが存在しない」状態になるため
  • 複合インデックス
    • (col1, col2, col3)というINDEXに対して WHERE col1 = ? AND col2 = ? はインデックスが効くが、 WHERE col2 = ?WHERE col1 = ? AND col3 = ?は効かないよ
    • 例えば「アーティスト名・アルバム名・曲名」という並び方で作られた索引に対して、「アーティスト名」だけで探す〜はできても、「曲名」を条件に探すっていうのは効率悪いでしょ(それなら全部スキャンしちゃうかもね)っていうイメージ
  • インデックスと順序
    • INDEX RANGE SCANはインデックスの順番で結果を返す
    • 複合INDEX(col1, col2)を作った場合、「col1で絞り込んでcol2でソートする」のようなwhere/order byを付けた場合でも、INDEXをスキャンした通りの結果をそのまま返せる = DBは明示的なSORT工程を踏む必要がない
    • ただ、これは「col1で絞り込んだ範囲であればcol2が順序よく並んでいる」といった場合に限るので、クエリの改修に注意が必要な感じ

あとはこの辺りをもう少しちゃんと読み込みたい

use-the-index-luke.com dev.mysql.com

Clean Agileを読んだ

最近になってようやく・少しずつ「アジャイル」なるものに興味が出てきたな・・・というタイミングで、「新しくClaen Agileっていう本が出るよ」というのを、翻訳者の1人である角さんのツイートで知った。
こんな良いタイミングで、こんな良さそうな本!!と購入。最近、書籍購入の財布がガバガバなこともある。

読後の感想としては、「アジャイル(未)入門」な自分が触れても充分に楽しめた!
内容も然ることながら、文章が凄い読みやすかったし面白かったな・・全体を通じて、(しばしば技術書や翻訳書にあるような)専門的・歴史的・横暴で権威的な眉間にシワを寄せながら付き合っていかなきゃいけない箇所みたいなのがなかった。文量的な軽さも相まって、読みやすいな〜って感じ。

アジャイルやXPについての具体的なやり方・プラクティス・ノウハウについては踏み込みすぎず、あくまで「アジャイルって(本来は!)こういうものなんだぜ・・」という部分を語っている本だな、と思う。理念というか初期衝動というか。
アジャイルって聞いたことあるし何となく存在は知ってるんだけど、計画期間を短くして回すやつ?それ以上の違いってどこなんだろ?」みたいな雑な認識をしてる人が読んでみると、「なるほど、その辺りが本質なのか」という輪郭が掴める気がする。

まさに副題の「基本に立ち戻れ」という通り、これは「この先、具体的にアジャイルやXPについて学んだり実践したりして、少しずつ自分なりに理解を深めていく中で、何度も帰ってくるべき故郷みたいな本になるかもな」という予感。
もっというと、「2章: アジャイルにする理由」と「6章: アジャイルになる」の前半、「7章: クラフトマンシップ」かなぁ。本質さえ抑えておけば道を誤らない、”実装論”や”プラクティス”は些細なことになるのではないか?という感覚がある。その点、これらの章が本書の中でも「なぜ」「どうすれば」に簡潔に答えてくれているような気がして。


以下、読みながらとっていた読書メモを見返しながら、特に気に入った部分とか。

P43

アジャイルは速く進むことだと思っている人もいる。だが、そうではない。これまでそうだったこともない。アジャイルとは、どれだけうまくいっていないかをできるだけ早く知ることだ。できるだけ早く知りたいのは、そうすれば状況をマネジメントできるからだ。(中略)アジャイルはデータを生成する。アジャイルは大量のデータを生成する。マネージャーはそれらのデータを使用して、プロジェクトの成果を可能な限り最高にする。

"アジャイルは速く進むことだと思っている人もいる。だが、そうではない。これまでそうだったこともない。" は、読んでて1番「おぉっ!」と思った箇所かも。
「フィードバックサイクルを短くして、現状をしっかり見つめて機敏にやる」みたいな話だもんな、そうだよな・・「成功確度を上げる」というのと「速くする」ってぜんぜん違うよな。それに加えて、「要求とは常に変化し続けるもの」となれば、より「細かく方向修正していく余地を持つ」ことが大事になる。そのためにフィードバックを集めるのか。
”プロジェクトの成果を 可能な限り最高に する"、なるほど。

この「データ」というのは、例えばストーリーポイントの消化状況だったり、バーンダウンチャートに現れている状況だったり(この前節のタイトルが「アジャイルが生成するデータ」)。「能動的に(積極的に)フィードバックを集められるようにモニタリングして、”適応的”にやっていく」っていうことか。

P44

プロジェクトの鉄十字に戻ろう。「品質」「速度」「費用」「完成」だ。マネージャーは、プロジェクトから生成されたデータをもとに、どれだけの品質、速度、費用、完成度のプロジェクトにするかを決める。 そのためにマネージャーは「スケジュール」「スタッフ」「クオリティ」「スコープ」を調整する。

可変変数はどれか、という話。この後に「(クオリティは)速く進みたければ上げるしか無い」って書かれていて、なるほど「クオリティも非可変か」と思った。
ラクタを作っても遅くなるだけ!

P59

しかし、その新メンバーのトレーニングは誰が担当するのだろうか?これまでコードベースを雑然とさせてきた人たちだ。新メンバーはすでに確立されているチームでの振る舞いに従うことになる。 さらにまずいのが、既存コードが強力な手本になることだ。新メンバーは現状のコードを見て、チームの仕事を推測する。そして、雑然とさせることに加担し、それを続けていくことになる。

そう!!!!コレ!!!!!!!!!って感じ、思わず膝を叩きそうになった・・。 「プロダクトの成長性を規定するのは既存コード」みたいな感覚。この辺り、前にカンファレンスで話した時にも触れた部分に近い。
あと「腐敗は侵食する」という。ただ、よくも悪くも「コードを書いている内にプログラマの腕や見識は高まる」ものなので、つまり「既存資産が良いコード」である確率はゼロになるんだよな。 普段から「今あるコードよりちょっといいコードを書こう」くらいの気持ちを強く持つことは必要かもしれない、或いは「未来の誰かのお手本を作っている」という緊張感が欲しい。全力を出さないで良いと考える合理的な訳がなくなる。

P122

シンプルな設計とは、必要とされるコードだけを書いて、最もシンプルで、最も小さく、最も表現力のある構造を維持するプラクティスである。

  1. 全てのテストをパスさせる
  2. 意図を明らかにする
  3. 重複を排除する
  4. 要素を減らす

1はTDD当たり前として、2〜4は個人的に考える「良いコード = 筋肉質なコード」に近いなー!「最もシンプルで、最も小さく、最も表現力のある構造」って良すぎる。
プログラマーの意図を明らかにする」 = 「表現力を高める」で、「表現力を豊かにしたあとで、重複を排除する」なのか。 「すべての重複を排除したら、クラス、関数、変数などの構造的な要素の数を減らすべきであることを示している」。これも「ローカル変数をなくす・メンバを減らす・・を意識して徹底するとコードの読みやすさを上げやすい」っていう自分の体感に適う。


アジャイル〜〜なトピックだと、次は「みんなでアジャイル」→「アジャイルサムライ」→「エクストリームプログラミング」か「SCRUM BOOT CAMP THE BOOK」辺りを読もうかなぁ〜って予定

CakePHPにDIコンテナが入った(る)と聞いて見学に行ってきました

ということがありまして、20201005現在で「4.next」に取り込まれているスティタスです!
※ 現行の4.1のパッチバージョンについてはmasterに向けられるので、 4.nextは「次のマイナーバージョン」である4.2を指します

CakePHPにDIコンテナが入ったらどんな感じに使われるんだろう?」というのは個人的にかねてより興味範囲でした。
そこで、このタイミングで「どうやって取り込まれたのかな?」を見てみようという試みです。

なお、本文中の英語で表記している単語(※略称を除く)はCakePHP中のクラスや名称を、カタカナで表記している単語は一般名称を指しているつもりです。

  • そもそもDI/DIコンテナ?
  • CakePHPとDIコンテナの距離感
    • CakePHPとService Locator パターン
    • CakePHPとDI、或いはインクリメンタルな導入
    • CakePHPとDIコンテナ
  • まとめ
続きを読む

PHPファイルのgit-diffを見やすくする

小ネタ。

cakephpのPRをほげ〜〜〜っと眺めていたら

ということで、やってみるか!!となった次第です

cf:

試してみる内容

before

<?php declare(strict_types=1);

namespace App;

class Hoge
{
    public function __construct()
    {
        // @todo
    }

    public function __destruct()
    {
        // @todo
    }


    public function make()
    {
        // このメソッドで
        // 何かしらして
        // 良い感じに
        // 頑張ろうと
        // 思っています
        $args = func_get_args();
        file_put_contents($this->getOutputPath(), $args);
    }

    private function getOutputPath()
    {
        return __DIR__ . DIRECTORY_SEPARATOR . 'hoge_output';
    }
}

diff

25c25
<         $args = func_get_args();
---
>         $args = json_encode(func_get_args());

という感じで、Hoge::main()の6行目を修正してみます

試してみる

gitatributes設定無し

f:id:o0h:20201001103529p:plain

こんな感じで、class は分かりますが後は行数ベースで頑張る感じです

gitattributes設定あり

f:id:o0h:20201001103546p:plain

コンテキストの粒度が「メソッド main() の中である」という事を明示するようになりました! 詳細な情報がパッと見れるようになって嬉しいですね〜〜

(・・・何で拡張子.phpのファイルに対して「phpと見なして差分を扱ってください」って設定が必要なんだろ?)

これでfinalやtraitといったキーワードにも対応できるらしいです。
やっぱりgitとphpはソース読めるようになりたいな、と改めて思いました。。。

PHPお手軽スタートキットを作った

先日、色々と調べごとをした結果を踏まえて「よ〜し、いっちょ自分でコード書いて試してみっかな!ライブラリでも作るかい!!」って気分になりまして。
その際に↓みたいなツイートをしていたのです。この辺りの”標準”みたいなのあんま分かってないな〜って。

いちいち「何が必要かな・・?」って考えるの結構ストレスになりそう。CIとかテスト周りとか整えるのも面倒くさくない?
そんな事をボヤボヤと考えている内に「そういえばGitHubにテンプレートプロジェクトって機能があったよね、使ったこと無いな」と思ったので、「ぼくのかんがえる最低限整ったPHPプロジェクトの雛形」を作ってみました。

github.com (コミットがメッセージも切り方も適当すぎてぶん殴られそうですが・・)

「今どきなPHPプロジェクトってどういう感じなんだろ?」っていうのにも興味があり、自分なりに考えて”それっぽいやつ”は入れてみたつもり。

なお、必要なツールを考えるにあたってこのPHP QAツールがすごい!2019を参考にさせていただきました🙌

なにができるの

  • PHPの実行環境としてDockerfileを入れてある
    • IDEから叩くような想定。というかPhpStormのCLI Interpreter
    • 一緒にmysqlも入れた、docker-composeで使う
  • ✅ ↑にXdebugが入れてある
  • PHPUnitをサクッと動かせるようにphpunit.xmlを入れてある
    • 地味に書き方忘れません?
  • PHP_CodeSniffer, PHPStan, Psalmも入れてある
    • 「最初から入ってれば負担も少ないはずだ」と思って、レベルはぎっちぎちにした
    • phpcsはPSR-12とSlevomatCodingStandardベース、PSR-12とぶつかるルールとか一部緩和
    • phpstan-strict-rulesとphpstan-phpunit入れた
    • psalm/plugin-phpunitも入れた
  • GitHub Actionsでphpunit phpcs psalmを叩くようにしてある
  • ✅ ↑を実行した時にreviewdogでコメント飛ばすようにしてある

作ってて思ったこととか

  • とりあえず「最低限」ってレベルならコレでいけそ、って感じにはなった
    • 色々と触りながら育てていく前提
    • lint周りとか色々と気になる部分出てきそう
  • GitHub Actions自分で触ったこと無いんだよな〜〜*1やりたいな〜って気持ちもあったので、少し欲求が満たされた。良かった
    • CIの設定ファイルだけ入れておけばすぐに動くの便利だな、すげーやGitHub Actions
    • 毎回Dockerイメージをbuildしてるからキャッシュとかした方が良いんかな?
  • codecovとかのよく使いそうなSaaSの記述はどうしようかな、と思ったけど一旦入れてない
  • READMEファイル置いてあるけど、このレポジトリの説明どこに置けばいいんだろ?
    • READMEとREADME-exampleみたいなのを分ける必要がありそうだな、紛らわしいし
  • バッヂ類は充実させたいな!
  • composerのcreate-projectも対応させてみよ。やったことないし

他の人の考えたやつも見てみてぇ〜な〜〜

*1:後になって気づいたけどやった事あった・・w https://github.com/Connehito/cake-sentry/pull/35/files