石橋秀仁(zerobase)書き散らす

まじめなブログは別にあります→ja.ishibashihideto.net

『Redisによる透明な永続化層』の余談と没ネタ

Redisによる透明な永続化層』の余談と没ネタ。

値オブジェクトをアノテーションで定義することについて(余談)

エンティティと値オブジェクトの区別は、永続化層の関心事ではなく、ドメインモデリング上も重要な概念なので、ドメインに関するソースコードの中に値オブジェクトを定義するアノテーションが記述されていることには何の問題もない。

値オブジェクトの永続化(余談)

値オブジェクトをエンティティと区別せずに永続化しても、論理的には問題ない。値オブジェクトを、その記述対象であるエンティティのシリアル表現に含むのは、単なる最適化に過ぎない。論理的には等価である。

Redisと検索(余談)

Redisで検索機能を実現するのは大変だ。Redisでやらなければいい。Solrなどの検索エンジンと連携させればいい。検索用データをエクスポートすればいいだけだ。

リポジトリ(余談)

どっちにしろリポジトリって必要だなあって気付いた。リポジトリは(ぼくが嫌いな)ORMを表現しているわけではなくて、「大量のオブジェクトを管理する」という責務を表現しているんだよな。だから、特定の永続化方式(RDB、ODB、KVS、…)に関係なく、抽象的なインターフェイスで定義されるべきなんだ。追加・削除といくつかの検索メソッドを定義する。

// Scala
Employee find by name(name) foreach { employee => do something }

こんな風にしたい。

Active Record(余談)

ずっとActive Recordが悪いんだと思っていた。しかし、Active Recordを賢く使わないことが悪いのだと理解した。

Due to the coupling of database interaction and application logic when using the active record pattern, unit testing an active record object without a database becomes difficult. The negative effects on testability in the active record pattern can be minimized by using mocking or dependency injection frameworks to substitute the real data tier with a simulated one. - Active record pattern - Wikipedia, the free encyclopedia

Redisコマンドのサニタイジングやエスケープ(余談)

エンティティIDのサニタイジングは、Redisドライバーに任せる。

自分でRedisコマンド文字列を組み立てる場合は、エンティティIDが不正な文字(空白や改行など)を含まないようにサニタイジングやエスケープをする必要がある。

RedisのLua(没ネタ)

LuaスクリプトとしてRedisデータベース内で動かせば十分に高速に処理できるのではないか。と思ったけど、Luaスクリプト実行中は他のあらゆる操作がブロックされるので、現実的ではなかった:

no other script or Redis command will be executed while a script is being executed. - "EVAL – Redis"

集約(没ネタ)

集約元のオブジェクトのIDをキーとして、listにIDを追加する。

  • add: RPUSH {ownerClass}:{ownerID} {aggregateName}:{objectID} (*RPUSH)
  • read: LRANGE {ownerClass}:{ownerID} 0 -1 (*LRANGE)
  • delete: LREM {ownerClass}:{ownerID} 0 {aggregateName}:{objectID} (*LREM)

値オブジェクトとエンティティの区別がない方式なら、永続化されたエンティティの上書き更新は行われない。すべてが「集約メンバーの差し替え」という操作になる。なぜなら、属性値としての値オブジェクトも、"cardinality=1"の「集約」とみなせるからである。

しかし、実際には非効率なので、値オブジェクトはエンティティのシリアル表現に含める実装がよい。