11 Feb 2015, 02:20

関数型言語 (Scala) をどうオブジェクト指向の現場に持ち込むか? セミナーをきいた感想

はじめに

今日は, なんだか仕事のやる気も起きないアンニュイな気分だったので, 仕事をサボって社内で開かれたセミナーを聴きにいきました.

Scala による OO と FP のお話

スピーカーは, 浅海智晴さん.

話の内容は, “オブジェクト指向と関数型プログラミング (Scala)“について.

用語を復習しようと Google で検索していたら, 今日きいた話のスライド発見. 一生懸命メモをとったものの, ラッキー.

以下, 用語についての復習と感想を書く.

背景

ハードウェアのメニーコア, 大容量メモリ化によって, 性能のボトルネックが I/O ではなくて, アプリケーションとなってきた. アルゴリズムが勝負の世界. アプリがボトルネックになってきた. そのため, 言語レベルで平行・並列処理が書きやすい言語が求められるようになった.

Cloud Computing において, 異常が発生したら全体をとめるのではなくて, 一部を停止して運用を継続させる必要がある.従来の例外処理では処理する のが複雑になってきた.そのため, 言語レベルで分散コンピューティングや Fault Tolerant をサポートするような言語が求められるようになった.

所感

ストレージ業界にいることもあって, アプリが性能のボトルネックになるというはなしはよくきく.

以前, 次世代メモリと呼ばれている ストレージ・クラス・メモリ (SCM) の技術動向の話をきいたときにも同じはなしが出た. アプリがストレージの性能のボトルネックになるとわかったとき, 我々開発者はなにをすればいいのか? という質問がでたが, 答えは,

関数型言語をつかうこと

All SCM Array が数年後に実現したときにはじめて, プログラミングの パラダイムシフト が起こるかもしれない.

関数型言語とは

過去と現在の関数型言語の認識の違い.

昔は, 高階関数 をサポートする言語という緩い定義だった.

現代のモダンな言語の定義は違う!

現代のモダンな言語 (Haskell, Scala など) は,

数学的理論を背景にプログラムを記述する言語

数学をベースとするプログラミング

数学的理論とは, たとえば以下.

  • ラムダ計算
  • 数理論理学
  • 圏論

とりわけ, Monad が大事.Monad をつかって, どうつくるかという流れ.

所感

数学のベースについて, 以下の記事でまとめられているが,これがおもしろい. 数学がベースといってはいるものの, 数学のほんの一部分.抽象代数学がからんでいる.

自分は, 大学では一応応用数学を学んだ気がしたので, プログラミングと数学が結びつくという売り文句はとてもうれしいのだ.

ああ, 学生時代の苦しみは無益ではなかったのだと.

代数学は, 禅僧の修行のような単なる苦悩に耐え忍ぶ訓練だと思っていたので, まさか, 社会人になって再び群論にお目にかかるとは,学生のときには想像 出来ないことだった.

コンパイル = 証明

コンパイルを通すということは, 正しさを証明すること

関数型言語では, コンパイルが通るとバグがほとんどでない. 純粋関数の世界でプログラミングをすることによって, 実現できる. 背景には数理論理学がある.

このことがなぜ大事かというと, 並列プログラミングのバグとりは大変. テストですべてのバグをとれたという保証ができない.

関数型ならば数学をベースにして, バグがないことを証明することができる

関数型言語のメリット・デメリット

  • メリット
    • 高階関数を使った技が使える (それによってコードが短くなる)
    • 定理と証明
  • デメリット デメリットだけみると, 組み込み系ではほとんど出番なしな気がした. いつの時代も, C 言語最強?? いや, C で並列処理はつらい.

    質問時間に, 組み込み系では関数型言語は活用できますかと 質問してみたが, わかりませんという回答だったので, 調べてみた.

    有力候補は OCaml. 時間効率, 空間効率がいいらしい.

    マイナーな言語で ATS というものもあるが, 情報が少ない.

    分散システムを組むならば, Erlang もつかえるか? - 組み込みから生まれた言語 Erlang の時代が来る - 日経エレクトロニクス

    組み込み系といっても, リッチな環境の組み込み系ならばリソースなんて 関係ない?? Android は Java で動いているし, Scala だって.

Monadic Programming

モナドを中心にプログラムを組む方法.

モナドとは,

  • コンテナ
  • パイプライン
  • インタプリタ

モナドにはいろいろな種類がある.

  • IO モナド
  • State モナド
  • Future モナド …

モナドの使い方は難しいのだけれども, パターンがあるのでなれれば簡単.

所感

モナドはよくわからない.

しかし, 今日の話で距離が狭まった.

難解なもの, 副作用をもつものは, モナドに閉じ込めて隠蔽する. それによって, プログラムがスッキリする.

この言い回しは, OO におけるカプセル化 でもきいたような気がする.

難解なもの, 副作用をもつものは, オブジェクトに閉じ込めてカプセル化する. それによって, プログラムがスッキリする.

また, モナドには使い方があり, 覚えてしまえば簡単という話は, 以前まとめた関数型デザインパターンの話にもつながるのかもしれない.

Functinal Reactive Programming (FRP)

ある変化に応じて動作する, イベント駆動のプログラミング方法.

Reactive Programmig には, 2 つの種類があるように思う.

  • Actor Model
  • Monadic Model

所感

以下の記事がわかりやすい.

最近よくみかける用語だし, これから流行しそうな手法.

GUI, インフラ, ビッグデータ処理など様々な場面で浸透しつつあります. 今までは複雑すぎて作ることが難しかったアプリケーションが簡単に設計できるようになっていくでしょう.

リアクティブ宣言なんという, かっこいい文章も存在する.

Object-Functional Programming (OFP)

オブジェクト指向のパラダイムと関数型のパラダイムの両方を利用して プログラミングする.

上流工程では, 今までどおりオブジェクト指向設計で考えることになる. ユースケースで今までどおり要件定義をして, コンポーネント分割までする. そこから, オブジェクトかファンクションのどちらかつかって責務を実現する. なので, OOP と FP は共存関係にある.

OFP 新三種の神器.

  • トレイト
  • モナド
  • 型クラス

OFP を導入することメリットは, 以下.

  • 高階関数DSL を書くことで 開発効率 をあげる
  • Monadic Programming を行うことで並列処理の品質をあげる

どこに Functional Programming を適用するか?

Functinal Programming で書くと, バグが出にくいので, Functonal Programming の割合をできるだけ増やしていくのがベスト.

システム開発では, OO:FP の割合は 6:4 くらいか??

FP でつくるのに適した部分は, DSL の部分. OOP で, Framework と呼ばれている部分.

アプリ開発は Java でもいい. アプリ開発の基盤にある DSL 部分を 関数型でかく.

DSL

DSL とは,特定のタスク向けに設計されたコンピュータ言語. DSL は一種類のタスクをうまく実行することに集中したもの.

そして, FP (というよりも Scala) は, DSL を書くことに 適している (Scalable language). なぜなら, 簡単に独自の型や制御構造を定義できるので.

まとめ

去年から, 関数型言語をかじりはじめてきたが, 自分が理解してきた

  • Stateless
  • High-order function

という考え方は, いわゆる伝統的な FP の概念だということを知った. また, それにかわるモダンな考え方は Monad だということも知った. (OFP 新三種の神器)

モナドについては, ほとんどまだ理解できていないので, 今年はモナドに注目して学んでいくことにする.

個人的には, 関数型言語を並列処理どう適用するかという話をもう少し つっこんで知りたい. それも, Monadic Model を理解すると見えるかもしれ ない.まずは, Monad.

Next Action

今は (伝統的!) 関数型言語の聖典, SICP を読んでいるので, Monad はさておき, まずはこれを読み終えなければ.

4 月か 9 月に coursera の Scala の講義が開講されたらもう一度受けてみる. (なぜなら, 前回は落第して単位をもらえなかったから…)

Reactive Programming についても学んでみたい. 去年 coursera で講座が 開講されるのをまっていたのだが, 去年は開講されなかった. 今年も開講されなかったら, 11 月からアーカイブ講座をつかって学んで見ようと思う.

07 Dec 2014, 11:32

Java におけるポリモーフィズムの整理

はじめに

Haskell で型クラスというものを勉強した.

その延長で, 今までとてもいい加減に理解していた Java のポリモーフィズムについて再度復習した.

なんか, 用語の関係性をすごく曖昧に理解していた気がした.

Polymophism: 多相性

各要素 (定数, 変数, 式, オブジェクト, 関数, メソッドなど) についてそれらが複数の型に属することを許すという性質.

同種のクラスをカテゴリに分類してまとめ, 基本的な動作・設計部分を統一することで, オブジェクトインスタンスの扱いに柔軟性と規律を持たせるための機能.

多相性は 3 つに分類できる.

  • アドホック多相:
  • パラメータ多相:
  • サブタイプ多相:

たとえば Java だと以下に相当する.

  • アドホック多相: オーバーロード
  • パラメータ多相: ジェネリクス
  • サブタイプ多相: 継承, インタフェース

参考:

Polymorphic Type: 多相型

<div class="outline-text-3" id="text-unnumbered-3">
  <p>
    データ構造のコンテナ.
  </p>

  <p>
    データ形式に依存しないコンピュータプログラミング方式をジェネリクス プログラミングという.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0">ジェネリックプログラミング &#8211; Wikipedia</a>
    </li>
  </ul>
</div>

アドホック多相

オブジェクト指向におけるアドホック多相とは, オーバーロードに相当する. 多重定義ともいう.

パラメータ多相

型変数

<div class="outline-text-3" id="text-unnumbered-6">
  <p>
    多相型は宣言されたクラス, 関数に対して, 利用時に具体的な型を与える. これを型変数 (Type variable) という.
  </p>

  <p>
    Java の名前つけルールがあるらしい.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://java.keicode.com/lang/generics-naming.php">名前付けルール &#8211; Java 入門</a>
    </li>
  </ul>
</div>

Generic Type: 総称型

<div class="outline-text-3" id="text-unnumbered-7">
  <p>
    型付けされたプログラミング言語において データ型の定義とそれを参照する式 (型式) の一部にパラメタを許すことによって 類似した構造を持つ複数のデータ型を一括して定義して, それらを選択利用する仕組み.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://ja.wikipedia.org/wiki/%E7%B7%8F%E7%A7%B0%E5%9E%8B">総称型 &#8211; Wikipedia</a>
    </li>
  </ul>

  <p>
    オーバーロード (overload), 継承 (inheritance) と並んでプログラミング言語において ポリモーフィズムを実現するための一つの手段.
  </p>
</div>

言語ごとの実現方法

<div class="outline-text-3" id="text-unnumbered-8">
  <ul class="org-ul">
    <li>
      Java: ジェネリクス, ワイルドカード <ul class="org-ul">
        <li>
          <a href="http://futurismo.biz/archives/2750">Java でのジェネリックスの使い方まとめ | Futurismo</a>
        </li>
      </ul>
    </li>

    <li>
      C++: テンプレート
    </li>
    <li>
      Haskell: <ul class="org-ul">
        <li>
          リスト
        </li>
        <li>
          タプル
        </li>
        <li>
          Either
        </li>
        <li>
          Maybe
        </li>
      </ul>
    </li>
  </ul>
</div>

Subtyping: 派生型

データ型 S が他のデータ型 T と is-a 関係にあるとき, S を T の派生型 (はせいがた, subtype) であるという.

基本型のデータを処理するように作られたプログラムは, その派生型のデータでも正しく処理することができる.

基本型-派生型関係ではリスコフの置換原則 (Liskov Substitution Principle) が成り立つ.

2 つの方法がある

  • インタフェース: 型をグループで分類
  • 継承: 型を階層構造で分類

inheritance: 継承

<div class="outline-text-3" id="text-unnumbered-10">
  <p>
    ほとんどのクラスベースオブジェクト指向言語では, サブクラス (インヘリタンス) が派生型の概念を実現している.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://ja.wikipedia.org/wiki/%E7%B6%99%E6%89%BF_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)">継承 (プログラミング) &#8211; Wikipedia</a>
    </li>
  </ul>
</div>

override: オーバーライド

<div class="outline-text-3" id="text-unnumbered-11">
  <p>
    オブジェクト指向プログラミングにおいてオーバーライド (override) とは, スーパークラスで定義されたメソッドをサブクラスで定義しなおし, 動作を上書きすること.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89">オーバーライド &#8211; Wikipedia</a>
    </li>
  </ul>
</div>

interface: インタフェース

<div class="outline-text-3" id="text-unnumbered-12">
  <p>
    抽象データ型のメソッド.
  </p>

  <p>
    Object 型を分類し, 同じカテゴリに属するクラスに共通のインターフェイスを取り決める.
  </p>

  <p>
    implements ステートメントは, クラスたちのカテゴリ分類を明確にする方法.
  </p>

  <p>
    変数の型としてカテゴリクラスを指定すると, そのカテゴリを Implements したクラス (つまり, カテゴリに属するクラス) のインスタンスも格納できるようになる.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://homepage1.nifty.com/CavalierLab/lab/vb/clsmdl/polymorphism_02.html">ポリモーフィズムとインターフェイス</a>
    </li>
  </ul>

  <p>
    オブジェクトが, 共通のインターフェイスを実装している場合, 他のオブジェクトに置き換えることができる.
  </p>
</div>

<div id="outline-container-unnumbered-13" class="outline-4">
  <h4 id="unnumbered-13">
    どう分類するか?: 共通性/ 可変性 分析法
  </h4>

  <div class="outline-text-4" id="text-unnumbered-13">
    <p>
      オブジェクト指向のこころより引用.
    </p>

    <ul class="org-ul">
      <li>
        共通性分析:時間が経っても変化しにくい構造を見つけるもの
      </li>
    </ul>

    <p>
      共通性分析によってまとめられた概念を抽象クラスによって表現
    </p>

    <ul class="org-ul">
      <li>
        可変性分析:変化しやすい構造を洗い出すもの
      </li>
    </ul>

    <p>
      可変性分析で得た流動的要素は抽象クラスの派生クラスによって実装される
    </p>

    <p>
      設計手順:
    </p>

    <ul class="org-ul">
      <li>
        (抽象クラス) このクラスが持つ責務をすべて全うするにはどうようなインターフェイスが必要か?
      </li>
      <li>
        (派生クラス) この特定実装の中でどうのようにして与えられた仕様を実装できるのか?
      </li>
      <li>
        共通性: 時がたっても変わらないものを抽象クラスに
      </li>
      <li>
        可変性: 流動的要素を具象クラスに.
      </li>
    </ul>

    <p>
      クラスの集合がもつすべての責務を真っ当するために, インタフェースを用意する.
    </p>

    <p>
      Jim Coplien が提唱. p235 第 15 章から抜粋.
    </p>

    <ul class="org-ul">
      <li>
        <a href="http://www.amazon.co.jp/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%A8%E3%81%A8%E3%82%82%E3%81%AB%E5%AD%A6%E3%81%B6%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AE%E3%81%93%E3%81%93%E3%82%8D-Software-patterns-%E3%82%A2%E3%83%A9%E3%83%B3%E3%83%BB%E3%82%B7%E3%83%A3%E3%83%AD%E3%82%A6%E3%82%A7%E3%82%A4/dp/4894716844">Amazon.co.jp: デザインパターンとともに学ぶオブジェクト指向のこころ (Software patterns series): アラン・シャロウェイ, ジェームズ・ R ・トロット, 村上 雅章: 本</a>
      </li>
    </ul>
  </div>
</div>

型クラス

<div class="outline-text-3" id="text-unnumbered-14">
  <p>
    Haskell の概念.
  </p>

  <ol class="org-ol">
    <li>
      型は値をグループ化する.
    </li>
    <li>
      型クラスは, 型をグループ化する.
    </li>
  </ol>

  <p>
    この説明はわかりやすい.
  </p>

  <ul class="org-ul">
    <li>
      値 < 型 < 型クラス
    </li>
    <li>
      <a href="http://jutememo.blogspot.jp/2009/05/haskell.html">Haskell のモジュールの階層化と, 型クラス &#8211; パラメータ多相とアドホック多相 | すぐに忘れる脳みそのためのメモ</a>
    </li>
  </ul>

  <p>
    型を分類する点でいえば, Java のインタフェースと同義.
  </p>
</div>

おわりに

先月くらいにクラス設計をしていたときに, 会社である怖い人が,

継承とは, オブジェクトを分類するための手段なんだ!

といっていたが, ようやくその意味を理解した気がした.

24 Nov 2014, 14:25

抽象データ型とドメイン駆動設計の関係について

はじめに

この記事の続きです.

設計とはデータ型を決めること

前回の記事を引用すると,

アプリケーションを設計するということは, まずそのアプリケーションで利用されるデータ型を定義するということ

その後, 自分が定義したデータ型を操作するインタプリタを設計する.

Java をつかっているものの, Java はそれらのデータ型のインタプリタでしかない

オブジェクト指向設計とはなんだろうか?

そんなことを考えていたとき, オブジェクト指向設計の本としてもっとも名高い本, エリック・エバンズのドメイン駆動設計が本屋にあった

思わず衝動買いした.

ドメイン駆動設計

ドメイン駆動設計とは, Eric Evans の提示した設計手法. DDD と略す.

本はこれ.

データ型の設計とは

抽象データ型については前回の記事でまとめた.

抽象データ型もオブジェクトも性質と操作の管理の仕方が異なるだけで, 性質や操作自体は同一だ.

抽象データ型を設計して, 型のインタプリタを作成すること.

DDD でいえば, エンティティと値オブジェクトを決めて, それを操作するサービスや集約, 生成方法を決定すること.

両者はおなじことを言っているように感じた. アプリケーションで扱う型を決めるということは, ドメイン層における, エンティティと値オブジェクトを決めるということ.

これが, とりありず前半部分を読んだ感想だ.

DDD 本の前半まとめ

以下 DDD 本の読書メモ.

とくに, リポジトリの章は, 明日まさに仕事で考えないといけないことなので, とても参考になった.

基本原則 (前書きより)

  • コアドメインに集中すること
  • ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通 じてモデルを探求すること
  • 明示的に境界づけられたコンテキストの内部で, ユビキタス言語を語ること.

基本用語

巻末に用語集がある.

ドメイン

  • 知識, 影響, 活動の領域.
  • アプリケーションが対象とする業務領域.

ユビキタス言語 (p24)

ドメインエキスパートと開発者の間で使う共通言語.

  • モデルを言語の骨格として使用する.
  • チーム内のすべてのコミュニケーションとコードにおいて, 厳格にその言語を用いること.
  • 図, ドキュメント, コード, 会話において, 同一の言語を用いること.

UML

  • UML によって議論に確固とした基盤が与えられる.
  • クラス図と相互作用図がつかいやすい.
  • オブジェクトの名前や関係性を共有できる.
  • オブジェクトの概念, なにをおこなうかははっきり伝えることができない.
  • クラス図の操作名やコミュニケーションでそれとなくは伝えられる. はっきり伝えるためには, 補足的なテキストや会話が必要.
  • 説明のためのモデルはオブジェクトモデルである必要は全くなく, 通常はそうでないほうがよい.

ドキュメント

  • モデルは図ではない.図はコミュニケーションの手段に過ぎない.
  • 設計に関する本質的な詳細は, コードにおいてとらえられる.
  • すでにコードでうまくやっていることを, ドキュメントでもやろうとすべきでない.
  • ドキュメントは活動の役にたたなければならず, 最新の状態を保たなければならない.
  • ドキュメントを最小限にとどめ, その重点をコードと会話の補足に絞る ことで, ドキュメントを常にプロジェクトに結びつけた状態にたもつ.

モデル駆動設計 (P45)

  • 分析モデルと設計ととう二分法を捨て去り, 両方の目的に 使える単一のモデルを探し出す.
  • モデリングと設計のプロセスは, 反復されるただ 1 つのループ.
  • 設計で必要とする用語法と責務の基本的な割り当てをモデルから引き出すこと.
  • 開発は, モデルと設計, コードを単一の活動として改良しつづける, イテレーティブなプロセスとなる.

モデル駆動設計の構成要素 (p65)

レイア化アーキテクチャ (p66)

以下の 4 つに分解される.

  1. UI 層

    ユーザとの相互作用の境界となる層 (Web 層, プレゼンテーション層)

  2. アプリケーション層 (サービス層)

    ドメインオブジェクトを操作することで, ソフトウェアが果たすべき仕事を実現する層. 薄くシンプルにたもち, 仕事はドメイン層のオブジェクトにやらせる.

  3. ドメイン層

    ビジネス上の概念を表現する層.モデル層

  4. インフラストラクチャ層

    上の 3 層を支える技術的な基盤となる層. データベース, 通信など.

エンティティ (参照オブジェクト) (p87)

属性ではなく,連続性と識別性によって定義されるモノ

  • 連続性
    • 状態をもつ.
    • ライフサイクルをもつ.
  • 識別性
    • 一意であることが保証された記号をそえることによって実現できる.
    • ID, 座席番号, 出席番号… システムが生成する.

振る舞いと属性を, 他のオブジェクトに移動できないか検討する. (別のエンティティ, 値オブジェクト, サービス..)

値オブジェクト (p95)

事物の特性を記述するオブジェクト. 概念的な同一性はない.

  • 識別子を持たない (与えてはいけない) 属性にのみ興味がある.
  • オブジェクトは不変でなければならない (fatal)
  • 通例読み出し専用のオブジェクト.
  • Flyweight パターンを用いて共有できる.
  • しばしば, オブジェクト間のメッセージでパラメータとして渡される.

サービス (p103)

  • 操作をおこなう責務をもつ.
  • ソフトウェアが実行すべきことに対応し, 状態には対応しない.
  • オブジェクト自身に操作をさせずに, それぞれごとにオブジェクトの操 作をするものは, しばしばマネージャーと呼ばれる.それは手続的だ.
  • 状態をもたせないこと.
  • 要求に応じてクライアントのために行われるなにか. なので, 名詞よりも動詞として定義される.
  • 操作名がユビキタス言語の一部になること.

モジュール / パッケージ (p108)

  • モデルの意味ある一部.
  • モジュール内は高凝縮, モジュール間は低結合.
  • モジュールは本で言えば章.
  • モジュール名は, ユビキタス言語をつけること. ドメインに関する深い洞察を反映していなければならない.

ドメインオブジェクトのライフサイクル (p122)

集約 (Aggregates) (p123)

  • 関連を最小限にして設計する.
  • モデル内にある参照をカプセル化するための抽象化が集約.
  • 関連するオブジェクトの集まりであり, データを変更するための単位. -> 集約のときに宣言する型は抽象クラスかインタフェースになるのかな?
  • 集約にはルートと境界がある.
    • ルート
  • 集約に含まれている特定の 1 エンティティ.
  • 外部オブジェクトへの参照をもつ.(車がルート, タイヤは違う)
  • グローバルな一貫性をもち, 不定条件をチェックする最終責務をも つ.(リソースの開放処理とか?)
    • 境界 * エンティティと値オブジェクトを集約のなかにまとめ, 各集約の周囲に境界を定義すること.
  • 境界の内部に存在するオブジェクトへのアクセスは, ルートオブジェクトを経由して制御すること.

ファクトリー (p134)

  • オブジェクトや集約全体を生成するのが複雑だったり, 内部構造をさらけ出し過ぎている場合は, 別のオブジェクトに移譲すること.
  • ファクトリーでカプセル化する.
  • 実装を簡単に切り替えられるようにできる.
  • 要求される型によって抽象化する.
  • デザインパターンでいくつかまとまっている
    • ファクトリーメソッド
    • ビルダー
    • アブストラクト・ファクトリー
  • ファクトリの置き場所は,
    • 集約のルートオブジェクトにメソッドを用意する.
    • 他のオブジェクトの生成に密接に関わるオブジェクト.

リポジトリ (p146)

  • オブジェクトを使用するための方法は

    1. 生成する
    2. 関連を巡る
    3. クエリを実行して,
      • 属性に基づいてデータベース内でオブジェクトを見つける
    • オブジェクトの構成要素を見つけて, それを再構築する
  • この第 3 の方法こそがリポジトリ.

  • データベース検索は, グローバルにアクセスすることができて, どんなオブジェクトにも直接到達できる. オブジェクトのネットワークは管理しやすくなる.

  • 開発者は通常, そういう設計の機微についてあまり考えない.

  • 格納されたデータからインスタンスを生成することは, エンティティのライフサイクルの一部. なのでこれを再構築と呼んで, 生成と区別する.

  1. 関連でほとんどの場合は十分!

    • 一時的なオブジェクト (値オブジェクト) は必要ない. ライフサイクルが短く, それを利用するクライアントで生成と破棄がされる.
    • 永続化されりオブジェクトのうちで, 関連を巡ってみつけるほうが便利 なものに対しても, クリエによるアクセスは必要ない. なによりも, 集約内部にあるどのオブジェクトも, ルートから辿る以外の方法でアクセスすることは禁止だ.
    • 永続化された値オブジェクトを見つけるには, それをカプセル化する集約のルートとして機能するエンティティから関 連を巡るのが普通のアプローチ.
  2. どのようなときに検索が必要?

    • オブジェクトの属性に基づいた検索を通じて, グローバルにアクセスできなければならないものもある. そういうアクセスを必要とするのは, 集約のルートのうち 関連を巡って到達しようとする都合の悪いもの.
    • データベースへのアクセス方法はいくつかある
  3. リポジトリの作り方

    • リポジトリは, 特定の型のオブジェクトをすべて概念上の集合として表現する. この定義の集合を通じて, 集約のルートに対するアクセスが提供される.
    • クラアイントがリポジトリに対してオブジェクトを要求する際は, クリエメソッドを使用する.
    • グローバルアクセスを必要とするオブジェクトの各型に対して, あるオブジェクトを生成し, その型のすべてのオブジェクトで構成され るコレクションが, メモリ上にあると錯覚させるようにできるようにすること.
    • 実際に直接的なアクセスを必要とする集約ルートに対してのみ, リポジトリを提供すること.