オブジェクト指向についてそろそろ一席ぶっておく

きっかけ

たまたま?最近よくオブジェクト指向の理解方法について、続けていくつかの言及を読んだ。

オブジェクト指向が5000%理解できる記事 - Qiita

オブジェクト指向との付き合いも長いし、これについて考えたり話すの結構好きなのでそろそろ一席ぶっておこうと思う。

オブジェクト指向との付き合い

15歳のときにC++を初めてそろそろ15年になる。少なくとも高専2年のときぐらいからオブジェクト指向について悩んでいたためそこそこうるさいと自認している。

僕のオブジェクト指向(記述)の書き方の理解のベース

僕はオブジェクト指向の記述方式をあくまで手続き型言語(ミュータブルな変数と関数)の延長線上だと捕えている。 これはCからC++へ流れてきた人間にとっては理解しやすい考え方だと思う。 構造体と関数がセットになったものがクラスとよく説明されたからだ。

なぜオブジェクト指向の理解方法についてはフレームしやすいのか

今回の一連の流れの発端となった?Qiitaの記事についても案の定反応は荒れている。 はてなブックマーク - オブジェクト指向が5000%理解できる記事 僕も正直この説明はどうかと思うが、オブジェクト指向について明確な定義がないため*1おまそう*2以上の反論がしづらい。辛いね。

そもそもオブジェクト指向は難しい

オブジェクト指向について理解するためには、そもそもプリミティブな型と関数を最低限理解する必要がある。 そこをちゃんと理解して、さらに構造体*3も理解した上でないとそもそも言語が提供するクラスという機能を理解することすら難しいのだ。

そのためプログラミング初学者が最初からクラスを使おうとするのはかなり無謀だと思う。

オブジェクト指向に明確な定義はない。たぶん・・・

XXであるのがオブジェクト指向である、というような一般に言われる定義はまだない。 たぶん各言語仕様で提供されるクラスに関係した機能と、それの一般的な利用法から事実上定義されているにすぎないと思う。

本題、僕のオブジェクト指向との付き合い方

前置きが長くなった。本題に入る。

僕はオブジェクト指向で書くとき、常に手続き型、つまりクラスのない変数と関数のみの構成から始める。 main関数内にそれらをベタ書きし始めるのだ。

そのうち、というよりすぐにコードで溢れてくる。 そうなってきたら、この各変数と関数を点として頭の中でマップのように配置する。 お互いの関係性が強ければ近い位置に、関係性が薄いかまったくなければ離す。 こうしてできた関数と変数の集合をそのままクラスにしている。

この話、ポリモーフィズムについてはほぼ全く考えていないが、実際ポリモーフィズムや継承はあんまり重要視していない。 それらはなくても大抵の場合問題ないし、大抵の場合使ったことにより問題が起こることのほうが多い。 言語の標準ライブラリやプリミティブ型が継承やポリモーフィズムを強制するのでない限り、少なくとも最初の方は自分のコードで継承・ポリモーフィズムは使わないほうが良いと思う。 でないとそれらの機能に振り回されて、本来自分のやりたいことから注意が逸れてしまいがち。

この考え方の背景

www.amazon.co.jp www.amazon.co.jp www.amazon.co.jp

これらを読んだにもかかわらず、18歳の時点で僕はオブジェクト指向をよくわかっていなかった。 結局のところ僕のオブジェクト指向への見解は習うより慣れろでコードを書き、時に読んで試行錯誤した中、うまく行ったパターンを繰り返して洗練させたものにすぎない。

ただ、上のような脳内マッピングイメージで理解し始めたのにはきっかけがある。 それは高専の哲学の授業で、言葉とは何か、その成り立ちについての講義のとき、 言葉、もっというと名詞とは点ではなく線で囲われた面であるという話があった。 海外には昔は津波という単語がなかったが、それが日本から輸入されたときそれまでbig waveでひとくくりにされていた言語範囲が線により二分され、片方はtsunamiに、もう片方はbig waveになった、というような説明だったと記憶している。

*1:本当にそうか調べてないけどね

*2:お前が思うんならそうなんだろう、お前の中ではな、という強引な主張に対する万能反撃

*3:ここではC言語のそれのようなメソッドを持たない2つ以上の型のペアのそれ

(駄文) MVCも階層化アーキテクチャもCleanアーキテクチャもどうでもいい。外形テストと継続的なリファクタリングをしろ。

アーキテクチャは正直なところなんでもいい。MVCで作ろうがDDDで作ろうがOnionだろうがCleanだろうが押し並べて、使えない。移ろいやすくて2年ごとに変わって、そのくせ完全に理解しないと使えないと喚いた上で、十全に理解した上で使うとまるで銀の弾丸であるように喧伝される。繰り返す、使えない。

それはまさにジャーゴンの代表みたいなものだ。ソフトウェアアーキテクチャの提唱については結局のところ次の1枚に集約される

f:id:den8:20180816020213p:plain

僕はアーキテクチャが無駄だといっているわけではない。MVCもMVVMもDDDによるLayerd architectureもOnionもCleanも無秩序なコードに一定のルールを課して、プログラミングの指針を示そうとしている。

でも、そんなもの結局のところ2年毎にシステムの開発担当者が変わるような職場で完全に理解を共有する、共有し続けることは不可能だ。DDDのディの字も知らない人間がコードライティングに参加するかもしれないし、後任のリーダーが突然今日からDuty Architectureにすると言い出すかもしれない。

だから僕は、内部アーキテクチャよりも外部とのインターフェイス、マイクロサービス的な視点で外部に露出したRESTやAMQPなどの接点を偏重と言っていいまでに重要視する。そこは内部アーキテクチャと違いそうそう変えられないからだ。

一方インターフェイスが同じであれば内部アーキテクチャなんてものは結局のところいつでも変えられる。

だからこそ、僕は単体テストを全く重要視しない。単体テストは内部アーキテクチャ、もっと言えばクラス構成と一蓮托生だからである。それはプログラマーにもったいない精神を生み構造的リファクタリングを意識的・無意識的に阻害する。

だからこそ、僕は統合テスト・外形テストと呼ばれるシステムインターフェイスレベルのテストを偏重と言っていいまでに重要視する。そこはめったに変わるものではないためだ。またそれはシステムの仕様になる。それはシステムの利用者との契約であり、ドキュメントである。

そして、(実はこっちがもっともいいたかったことだが)アーキテクチャなんかより継続的にリファクタリング・テスト・リリースできる開発環境の構築こそが内部構造なんかより10倍ぐらい重要なんだ。

コード書き始めて15年、業務アプリケーション開発に携わって6年だが、この6年の間にそのときのリードコーダーのきまぐれで選ばれたアーキテクチャで作られた、たくさんのひどい業務アプリケーションに携わった。少なくとも片手では数えられない程度のシステムは見てきている。

その全てが最初は理想的で、革新的で、この世のすべてのソフトウェア開発問題を解決する素晴らしいアーキテクチャを使って書き始められた。 しかし、現実はどうだろう。 リードコーダーは転職し、後任のコーダーは新卒1,2年で、当初の理想は見る陰もない。そこには仕様すら定かでない業務アプリケーションが転がるだけだ。

認めろ。内部アーキテクチャなんぞに俺のクソほどの価値もない。 それは理解されず、徹底されず、6ヶ月ごとに入れ替わり2年で移籍する開発者へ教育する価値もなければ時間もない。業務アプリケーションのコーディングへ携わる人間すべてへ同じアーキテクチャへの理解を強制することはできないし、現実的ではない。

そんなものより、変わりゆくシステム要求を満たしつつ成長し続けられる開発環境こそが重要なんだ。 ここでいう開発環境とはIDEのことではない。 システムインターフェイスのサービスディスカバリ、API仕様の発布、APIドキュメント、CI、CD、漸近的でPRベースの開発スタイルすべてのひっくるめである

単体テスト、つまり内部クラスのテストではなく外形テスト、システムインターフェイスのテストをしろ。 それもakka-http-testkitやその他のコントローラ専用テストツールを使うのではなく、実際にサーバを動かしてsttpやその他httpクライアントライブラリを使って実際にREST APIを叩くんだ。

ほとんどの人間がやったことがないので最初は面倒に感じるかもしれないが、それはそんなに難しくない。 もし仮にそれがそんなに難しいとしたら、お前たちはそういうひどいものをシステム利用者に提供していることになる。それはそれでいい教訓になるだろうし、次からはもう少し頭を使ってAPIをデザインするようになるだろう。

あと、前述の通り内部アーキテクチャは2年毎に変わるから、導入するにしても極力シンプルなものを導入しろ。それも広く使われている用語を使ってだ。

例えば、かなりハイレベルな職場ですら全体で確かに共有できるものはせいぜい以下ぐらいのものだろう。

  • リポジトリ: DBや外部サービスとのやり取りを集約する
  • エンティティ: リポジトリから取り出されるもの、リポジトリで保存されるもの
  • サービスやユースケースなんてものは作るな。それは物(Object)ではないし、オブジェクト指向の原則から外れる。それはロジックとデータ構造の関係を曖昧にする
  • 便利(util)クラスも同じ。経験上、implicit classやオープンクラスを活用することで継承を使うことなく機能を追加できることがほとんどだ

slackでの連絡は直接口頭でのやり取りが面倒くさいからじゃないよという話

slackでの連絡は短期的なメリットと長期的なメリットそれぞれ1つずつある。

短期的なメリットはこれが口頭でのやり取りではなく非同期式コミュニケーションであることで、 特にコンテキストスイッチのコストが非常に大きいプログラミング作業中のエンジニアにとって非常に便利である。

長期的なメリットは単純ながら記録が残ることで、年単位で務めると威力を発揮しやすい。 一方でDirectMessageによるやりとりは検索に素直に出てくれないので困る。 slack開発元には可視性がPublicのDMを実装してほしい。

swagger-playやswagger-akka-httpのようなフレームワーク連携swaggerドキュメント生成ライブラリは概ね役に立たない

swagger-playやswagger-akka-httpのような、フレームワークと連携してswagger ドキュメントを自動生成してくれるようなライブラリがある。 このようなライブラリは直接API仕様をyaml/jsonで書く必要がなくなり、swagger仕様も読み解く必要がないため一見便利に見えるが使ってみたところ以下の欠点があり現時点ではプロダクトで使うには足りなかった。

1. フレームワークとの統合に限界があり、それほど自動生成してくれない

ライブラリがフレームワークから自動生成してくれる情報はせいぜいAPIパスとメソッド(GET/POST/...)などで、ヘッダ情報やレスポンスのステータスコードのパターンなどは結局自分で書く必要がある。

2. アノテーション情報が非常にコード品質を落とす

上で述べた通りほとんどの情報は自動生成されないのでメソッド/クラスへのアノテーションとして各種情報を書く必要があるが、swaggerドキュメントの品質をあげようとするとこのアノテーションは1APIにつき簡単に10行以上にもなりコードの可読性を著しく下げる。 そのためswaggerドキュメントの品質を上げようとするとコードの品質が下がり、コードの品質を上げようとするとswaggerドキュメントの品質が下がるというジレンマが発生する。

3. ライブラリのコード品質が低い

上のような欠点により多くの人が早めに見限るので、ライブラリの品質が基本的に低い。 swagger-akka-httpswagger-playを試したがどちらも有名ライブラリと連携している割にはstarが少なく、またコードの品質が低かった。 具体的には以下を指す。

  1. アノテーションで表現できないswagger仕様がある
  2. swagger仕様のバージョンアップに追従していない
  3. case classとswagger modelを紐付けるなど比較的簡単に思いつきそうな機能がない

結論

swaggerドキュメントとコードは切り離して管理したほうが良い。 その方がコード/ドキュメントそれぞれの品質が上げやすくなる。 コードとドキュメントの歩調を合わせる手間の問題についてだが、個人的にはAPIサーバのrootにアクセスしたときswagger UIでそのAPIサーバのswaggerドキュメントが動くAPI仕様として使えるようにすればかなり楽になると思う。 例えば https://api.petshop.io/api/v1/xxxx のようなAPI集合がある場合、https://api.petshop.io/ へアクセスしたときswagger UIで https://api.petshop.io/api/v1/xxxx 系のAPIの仕様すべてを表示する。 これには以下の利点がある(番号が若いほど重要)。

  1. API利用者がswaggerドキュメントの場所を探す必要がなくなる
  2. 動くAPI仕様書は使いやすく、その結果API使用者・記述者両方がよく利用するようになる。その結果仕様の間違いや足りない記述などが発見されやすくなり、ドキュメントを修正しやすくなる。最終的にAPI仕様書の質が上がるようになる
  3. APIの追加/機能変更とドキュメントの更新を同じパッケージ(jar)で賄うことができ、それによりswaggerドキュメント変更とコード変更の歩調が簡単に合わせられる
  4. Swagger UIと対象APIが同じホスト名ならCORSを考慮する必要がない

動くAPI仕様書と実際のAPIを同じドメインにまとめることの利点はWeb API Design(その4) - winplusの日記の「ひとつのサブドメインに、APIのリクエストをまとめる」でも語られている。

chromeから複数アカウントでツイートしたい

検索キーワード: Hootsuite Hootlet chrome multi account just tweet share page

前提条件

  • ChromeからTweetがしたい
  • Twitter複数アカウントを切り替えながら使っている
  • TLを見ると集中力がそがれるので一方的にTweetするだけにしたい
  • url shortenerは使いたくない(セキュリティ上の問題などあるため)

解決案

  • ❌ TweetDeck
    • マルチアカウントに対応できるがTLを見ず投稿する機能はない
  • ❌ Hootsuite Dashboard
    • マルチアカウントに対応できるがTLを見ず投稿する機能はない
  • Share on Twitter - Chrome ウェブストア
    • TLを見ず投稿できるがマルチアカウントに対応していない
  • Just Tweet ボタン - Chrome ウェブストア
    • TLを見ず投稿できるがマルチアカウントに対応していない
  • Hootsuite Hootlet - Chrome ウェブストア
    • マルチアカウントに対応できTLを見ず投稿する機能があるが、動作が不安定
      • そのページ内でJavaScriptを動かすためgithub.comのようなページで実行するとエラーで動作しない
    • URL shortenerを無効化できない
    • おまけにgoogle検索結果やgoogle mapなどへ勝手に変なリンクなどを挿入する。XXXX
  • 🔺 hootletのbookmarklet( Hootlet Link Share Tool - Hootsuite の下部 )
    • マルチアカウントに対応できTLを見ず投稿する機能があり、動作が安定している
    • URL shortenerを無効化できない
  • ⭕ [上のbookmarkletを参考にしたURL shortenerを使わないオリジナルbookmarklet(Just Tweet With Hootsuite - Hatena::Let)
    • マルチアカウントに対応できTLを見ず投稿する機能があり、動作が安定している
    • URL shortenerもトリックで(URLとしてではなく単なるテキストとしてAPIに渡す)無効化できる

結論

Just Tweet With Hootsuite - Hatena::Letを使いましょう。

PofEAA感想 14章~18章

第14章 Webプレゼンテーションパターン

ビューとコントローラの分離は、比較的重要ではなく、必要なときにだけ分離を実践することを推奨する。

なるほど、そういう考えもあるのか。

多くの人にとって基本的なWeb環境とは、静的なHTMLページである。

時代は、変わった・・・。

トランスフォームビュー、ツーステップビューなどは飛ばす。今はclient(ブラウザ)側でもMVCバリバリなコードを書くのでサーバがUI(HTML)を描画して返す時代ではない。

第15章 リモートファサード

ここで説明していた役割は今RESTful APIサーバなどに変わっていると思う。 なので流した。

第16章 オフライン並行性パターン

軽オフラインロックは楽観的オフラインロック、重オフラインロックは悲観的オフラインロックと読み替えること。

楽観的オフラインロックの仕組みとしてはバージョン番号(auto incrementな整数のイメージ)を使う。 タイムスタンプはシステムクロックが当てにならない、特に複数サーバの場合同期が保証できないので使わないほうがよい。 master-slave型のDBであればDB側に時間を挿入させることでタイムスタンプを使ってもよいかもしれない。

一貫性のない読み込みと楽観的オフラインロックで防ぐ方法、タイムスタンプを使えば楽だと思ったがウェブサーバとDBサーバの時間が完全に同期していることを保証するのは難しいのでこのアプローチはいまいち。

(意訳) checkCurrentメソッド - 今他の誰かがデータを更新しているかどうかをバージョンカラムの値などからチェックする

書かれている通り長大なトランザクションを処理しているとき、その開始直後に失敗することが確定しているケースがある。 そういったときにこの関数でそれを予め知ることができれば非常に時間のかかるが失敗することが確定している処理に無駄な時間を割かなくて済む。

読み書きロック

これは非常にいいアイデア。何かのときに使いたいツールとして覚えておこう。

16.3 粗粒度ロック

エンティティツリー(DDD本では集合体 - aggregateと呼ばれているっぽい?)単位でロックを設定するパターン。

16.4 暗黙ロック

過去に関わっていた某システムで最用紙していた方式。 ただ、あまり良い方式には思えなかった。結局の所程度の差はあれプログラマートランザクションを常に意識する必要があり、それを暗黙的にすることはあまりよさそうではない。usingパターンを利用して勝手に開放してくれるようにするのはいいと思う。

17 セッションステートパターン

クライアントセッションステートが現代のWebアプリケーションでは良いのではないかと思う。 サーバセッションステートもデータベースセッションステートもスケーラビリティに欠け、また純粋なHTTPの考えに反する。 クライアントのコミット前の情報はクライアントサイドで持つべきである。

第18章 ベースパターン

基本的に今まで参照してきたのでスキップできる。

終わったー

PofEAA感想 9章~13章

第9章

P123

ドメインモデルっていろいろ曲解誤解されがちだけど、基本的にはデータとメソッド(振る舞い)を同じものに持たせるという古典的なオブジェクト指向そのものなんだよな。 トランザクションスクリプトやテーブルモジュールなんてものがむしろ基本的なオブジェクト指向の考えに反しているだけで。

~さらに継承が使われるのである。

現代のモダンな言語では継承は使いたくないなあ。

読んでいて思ったけど、近年の言語ではデータとメソッドとの区別が非常に曖昧になりつつある(RubyしかりScalaしかり)。 もはやオブジェクト指向定義上の「オブジェクトとはデータと振る舞い(メソッド)を持つ」というのは古くて、 内部状態としてのデータと外部インターフェイスとしてのメソッドを持つ、といった表現のほうがよりモダンなんじゃなかろうか。

P128

ドメインモデルで共通して見られるのは、複数のクラスが最もシンプルなタスクでも相互作用する方法である。この方法では、オブジェクト指向プログラムで膨大な時間を掛けてクラスからクラスへと探し続けなくてはならないというストレスを引き起こすことがある。

わかる。 ただドメインモデルのためにその欠点を飲んでやるってことは、長期的・より発展的な開発ではメリットがあっても短期的にはむしろトランザクションスクリプトでオブジェクトを活用せずprimitive型とarray、あと関数のみで書いたようなひどくシンプルなものののほうがわかりやすくなるっていうのが逆説的にはっきりした。

(意訳)ドメインモデル、というよりより純粋なオブジェクト指向は分岐をなくす

たしかに。

P 134

anEmployeeModule.getAddress(long employeeID)

テーブルモジュール、今まで1テーブルを1オブジェクトに紐付けると書いてあって訳し間違いか解釈の違いかと思ったら本当にそうだったのか! 複数レコードの集合としてクラスを定義するのはアリだとしてもそれは1レコードに対して1オブジェクトを対応付けた後のオブジェクト集合としての立ち位置が本筋で、集合の方のみをオブジェクトとするのはナンセンスな気がする。 これは現代ではまったく主流じゃないし、アクティブレコードすら1レコード1オブジェクトを返している。これは詳しく読まなくても良いかもなあ。

9.4

ここら辺のサービスレイヤの話はかなり眉唾。 DBやビジネスロジックなどのより具体的なレイヤーわけ理由がサービスレイヤにはない気がする。 アイデアとしてはありなのかもしれないが実態としてはエンジニアそれぞれが自分のサービスレイヤ定義を持ち始めて収集がつかなくなるリスクのほうが高い。 私はできるかぎりサービスレイヤの定義・利用は避けたい。

9.4.2

(意訳)クライアントが1種類で、リクエストレスポンス上で複数のトランザクションが絡んでいない場合は不要。 言い換えると複数の種類のクライアントをサポートしたい場合のみ利用するべき

だよなあ。ただしこの記述に反してサービスレイヤは乱用されている気がする。

第10章

テーブルモジュール、だいぶイメージがわかってきた。.NETで顕著らしいがUIのカラムビューでそのまま表示できるように、複数レコードをそのままアプリケーション内で長く持ち運ぶような環境だとよいっぽい。 でも実質的に.NET専用なんじゃないかなと思う。

今更だけど、この使用するタイミングって節死ぬほど大切だな。ここをちゃんとチェックすれば誤用を避けられるし変な使い方をしている人やシステムに対してこれをproofとして反論できる。

(意訳) 行データゲートウェイとアクティブレコードの違いは前者はオブジェクトにドメインロジックが含まれないが後者は含まれる

なるほど、これで行データゲートウェイが完全にイメージできた。

P170

Active Record uses the most obvious approach, putting data access logic in the domain object.

アクティブレコードはこれを使ってデータアクセスロジックをドメインオブジェクトに配置する。

これも相当やばい翻訳。 正しくは以下。

アクティブレコードはドメインオブジェクト内にデータへアクセスするロジックを置くという最も明快な方法を使う。

ここはてなブログが経過を消しやがって10ページほど記述なし

P183

一意性マッパー、やはりプログラム内でのここのテーブルに紐付けられたキャッシュ層か。 これはアプリケーションサーバが水平展開されるとまったく使えないテクニックなので基本スキップしていいかな。 この層をredisやmemcacheと言った揮発性の共有できる永続化層にて行う方法もあるが、そこまでやるならクエリベースでキャッシュするほうがシンプルそう。

一意マッピングはDBへクエリを投げるオーバーヘッドが期待より大きく、よっぽどパフォーマンスを最適化しないといけないケースでは選択肢の一つとなりえるかもしれない。それでもクエリベースのほうが良いような気はするが。何よりサーバが複数になると矛盾が発生するのが良くない。

第11章

なるほど、ユニットオブワークは単なる登録所、文字通り作業単位としてドメインオブジェクトを登録しておいてプログラムからのコミット呼び出しで登録されていたオブジェクトすべてに対してcommitを発信するのね。

登録時と比較して更新がなかったオブジェクトはSQL送らなくて良いとか書いてあるけど細かすぎる最適化の気がする。 おまけにオブジェクトが変わったかどうかでSQL発行されるかされないか変わるとなると挙動が複雑でよくわからないバグの温床になる。

これってtransactionとほぼ昨日同じでは?外部永続化装置がRDBMSのみならユニットオブワークを使う意味なさそうだな。

11.3 レイジーロード

ちょっとよくわからないものもある。レイジーイニシャライズとゴースト以外は具体的にイメージがわかない。 レイジーロード自体テクニックとしては重要だが必ずしも毎回使うわけではないのでレイジーイニシャライズ以外のテクニックはほとんど使わないんじゃないかと思う。レイジーロードをまとめる手法などはやりすぎだ。こんなものを使う前にオブジェクトの構造を見直したほうが良い。

レイジーロードの追加は、プログラムが若干複雑になるため、私としては本当に必要なとこき以外はあまり使いたくない。

禿同

P235

キーテーブル、こういった手法を見たことがある気がする。java用のスキーマ管理ツールやSCT・DMSなどでこういったものがあったよね。

第12章 オブジェクトリレーショナル構造パターン

この章、オブジェクト(レコード)間の相互参照をどうRDBMSオブジェクト指向言語の間で変換するかって話なのね。 オブジェクト指向言語ではひどく単純に参照元に参照先のポインタを保存するメンバー変数を用意するけど、リレーショナル・データベースでは1対多や多対多のケースで素直には行かない。 なのでRDBMSオブジェクト指向言語プログラミングの間では関係性をうまくマッピングしてやる必要があると。

12.5 依存マッピング

DDD本にエンティティ単位のオブジェクトグラフのアイデア(エンティティだっけ?)があった気がするけど、その単位でDBから読み出し/書き出す話。 根っこのドメインクラスにしかマッピング機構を持たないというのは自然だがたしかに良い方法。

12.6 シリアライズLOB

パフォーマンスクリティカルでもない限りそうそう使わない。だが文中でXMLならいいとこ取りできると言っていることは今ならJSONカラムがよりスマートに解決している。

レポート用

以前もレポート目的という記述があったが具体的にそれが何を指すかはまだ出てきてない。 さっさと実態を知りたいが、索引に載っている?

12.6~9 シングルテーブル継承、クラステーブル継承、具象テーブル継承

全部継承を使う前提なので基本悪手。オブジェクト指向の論理をRDBMSに持ち込もうとしているので簡単な部分ではうまく行くが問題が複雑になればなるほど歪みが増え、やがて破綻する。 そして僕らの仕事で簡単なことをできるケースはまれ。

第13章 オブジェクトリレーショナルメタデータマッピングパターン

メタデータマッピング、scalikejdbcだとcase class周りな感じか。 ただメタデータというメタデータは実際にないよね。scalaは表現力が高めなので内部DSLでなんとかできると解釈するか。

13.2 クエリオブジェクト

scalaの内部DSLSQLクエリを直接書くのではなくオブジェクトとメソッドの呼び出しで擬似的にSQLクエリを組み立てるテクニック。C#にもこういうのあったよな。

13.3 リポジトリ

ここの記述ではクエリオブジェクトを使うこと前提みたいに書いてあるけど、単純にエンティティツリーとRDBMSを直接紐付けるだけのレイヤーでもいいんじゃないかな。むしろクエリオブジェクトをわざわざ作るのはイケていない気がする。