nakajima jun
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    DDD本 9章 暗黙的な概念を明示的にする === ###### tags: `エヴァンス本読書会` # Discord開始位置 - [2021/01/23 Sat](https://discord.com/channels/432531367427964929/740202765619429487/802415932597075979) - [2021/02/06 Sat](https://discord.com/channels/432531367427964929/740202765619429487/807527863837523978) # 自己紹介 - なかじま(J.Nakajima) - ファシリ役 - タイムキーパー役 - こばやし(t2_Kobayashi) - 読み上げ役 # 参加の仕方 - マイクはいつでもONにして、話に参加して結構です。 - テキストチャットでも、コメントやリアクションでどんどん参加してください!ラジオ担当が拾っていきます。 - 聞いているだけの方もOKです! # ディスカッションをより豊かにするためのグランドルール - 参加者は毎回任意 - 今回は不参加、次回は参加をするといった気軽な感じ - 途中参加も断然OK! まずは聞くだけでも大丈夫です! - フィードバックを恐れない - マサカリは怖いと思いますが、アウトプットからのフィードバックを受け、学びを深めていきましょう - アウトプット7割:インプット3割の気持ちで臨みましょう! - 経験の有る無しは気にしない - 自分はDDD非経験者だから……と気後れする必要はないです - 堂々と意見や疑問を語りましょう - ページ数と同時に、節のタイトルやキーワードを言って頂けるとスムーズです - 電子書籍で読んでいるとページ数ではわからないため - 話していない人が、率先してメモしましょう - このHackMDはみんなのものです。どんどん書いていきましょう:+1: :+1: - 気になる質問や同感するものには :+1: を末尾につけてください。 # タイムテーブル | 時間 | 所要時間 | 内容 |備考 | | -------- | -------- | -------- | -------- | | 19:50- | - | 集合開始 | | | 20:00-20:15 | 15分 | 当日の流れとグランドルールの共有 | | | 20:15-20:25 | 10分 | 感想記入&HackMDに書かれた皆さんの感想・気づき・疑問をもっと掘り下げたいものを、 :+1: 付けていく | | | 20:25-21:55 | 90分 | 本の節ごとにディスカッション(ここでも適宜、HackMDに気づきとか書いていってもらっていいです) | | |21:55-22:00 | 5分 | 次回開催日と読む範囲決めてクローズ | | ## 下に感想などを書いていって下さい。どんな些細なことでもOKです。 --- # 第9章 序章 ## 目安の時間 - 30分 ## 感想・気づき - > P.207 ドメインモデルとそれに対応したコードが大きく変化するのは、議論で示唆されたり、設計の中に暗に存在したりする概念に開発者が気づき、それを1つあるいは複数のオブジェクトや関係性を使って、モデルの中で明示的に表現したときである - 暗黙的な概念を発見した時のあの興奮って、なんだろうなぁ。極端な言い方をするとそれを発見する前と後での世界がガラッと変わって見える。:+1: - 後になってから「実はこういう事もしたいんですよね」って追加で要望もらって気づくことも(議論で示唆された、の1つのバリエーションともいえる?)。確かに見え方がガラッとかわって、でも、状況によってはブレークスルーの章にもあったけど「我々を支配していた感情は恐怖だった」になりそう。:+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802503178549461003) - ドメインにおける本質的な概念を荒削りでもモデルで表現→暗黙的な概念をなんらかの形で掘り出す→数々の概念がモデルで明示的にされた後にリファクタリングという流れ :+1::+1: - 確かに概念が明示的じゃないと、リファクタリングが容易じゃないだろうなと思った。 - 中盤の暗黙的な概念を掘り出す、がこの章で取り扱うところ。 - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802502928501309460) - P.207 しかし、このプロセスは、暗黙的な概念を、荒削りであっても何らかの形で認識することから始まる。:+1: - とにかく、思う部分は正解でないにせよ表現してみるのが大事。:+1::+1::+1::+1::+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802498889663250462) - :memo: いったんたたき台でもお皿に乗せることで議論ができる感じですね。 - :memo: 空中戦は、各人何かしら認識してはいるけれど、認識の差分が共有されていない状態で、「暗黙的な概念を(,,,)何らかの形で認識」した後の段階感 - :memo: 「ここになにかあるぞ そこに何かがあるということ自体は、何を契機に気がつくのかしら。 - :memo: 僕は全部偽物だと思っています(今あるものが本質でない、のスタンスで探求) - :memo: 「このモデルはこうだ」と頭ごなしに決めつけるのが最悪 - :memo: ドメインエキスパートが信じているモデル像も、話を聞くとなんか違ったりとかあります - > :memo: ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探究すること。 ## 疑問 --- # 概念を掘り出す ## 目安の時間 - 30分 ## 感想・気づき ### 言葉に耳を傾ける - > そのような時に突然、頭の中の霧が晴れる。帳票に記載されたその項目の名前は、重要なドメインの概念を指し示しているのだ。 - **言葉に耳を傾ける** - Evansさん楽しそう - この「霧が晴れる」という現象は、Polanyi的な意味での「暗黙知」が発揮された感じがある:+1: - ドメイン全体をより上手に、より簡単に説明できるような知識・概念が、「暗黙知」によって秩序付けられた「全体」として統合された格好(Polanyi 『暗黙知の次元』) - Polanyiいわく、「暗黙知」によっていかにこうした「全体」が統合されているのかは、言語化されていないのではなく*言語化できない* - 一方で、「暗黙知」が作用するまでのプロセスは說明されていて、いわく、特定部分ではなく、あちこちへ散漫に"注意が移動"する中で、そうした「暗黙知」がなんらかの方法で統合させる、という:+1: - こうした「霧が晴れる」というのも、あちこちに目を向け注意を向け情報を得て、かつその移動を止めずあちこちへ移すという振る舞いがあってこそ、こうした統合が達成された(=霧が晴れた)のでは、という感じがある - この例だと、帳票の特定項目しか見ていなくても恐らくだめで、Evans自身が色々な知識をいろいろな観点からぐるぐる考え続けていたからこそ、こういう体験があったのではないかな、的な:+1::+1: :+1: - ましてや、コードしか見ていなかったら、ここで言うような例はなかなかおきないのではないのかな、という - 「コードを上手に分ける方法」という意味でのブレイクスルーは、それでも起こりうるだろうけれど - それも、コードの全体をあちこち見ていないと難しい気はする - だとすると、ドメインに対する深い理解を得たいのであれば、ドメインの部分部分について深く考えつつ、一方で、ドメインの部分ではなく全体をゆるやかに眺めるという、一見相反するような動きが重要、といえるのでは:+1::+1::+1::+1::+1::+1: - 連想 -> https://twitter.com/ShinShinohara/status/1352848325767163904 - > こうした考え方は、旧来の「名詞がオブジェクトになる」というものではない。新しい単語を耳にすることで手がかりができる。それを受けてさらに会話と知識の噛み砕きを続け、明確で有用な概念を切り出すことを目指すのだ。 - **言葉に耳を傾ける** - 新しい単語は「手がかり」であって、それをそのままオブジェクトにするのではない - 結果的に、"新しい単語"がそのままオブジェクトになることはあるだろうけれど、それは必須でも第一条件でもない - そうした「手がかり」によって”明確で有用な概念”を切り出すことが重要なのであって、「新しい単語」そのものに拘泥しても、ドツボにはまりそう:+1::+1::+1: - このあたりからも、ドメイン知識 ≠ 「業務知識」だし、ドメインロジック ≠ 「業務ロジック」という感じ - 業務に関する「新しい単語」を見つけたからといってそれを直接組み込むと、その瞬間の「業務〇〇」に固着してしまう感じ - 業務そのものというよりも、業務を成立させているルール・原理を見出す方向性に感じる:+1::+1: :+1: - > P.208 ユーザやドメインエキスパートが設計のどこにもない語彙を使用したら、それは警告のサインである。開発者とドメインエキスパートのどちらもが設計にない用語を使用したら、それは2倍の警告である。あるいは、それは好機ととらえた方がよいかもしれない。 - 前半部分はとても敏感になっていたけど、好機ととらえる発想はあまり無かった。 - ドメインエキスパートの話し言葉に無く、開発者が独自で使っている言語は不吉感がとても強くなるが、もしかしたらそれはドメインエキスパートの複雑な行動を端的にまとめている可能性もあるかもしれないな、と思った。:+1::+1::+1: - その名前、概念に対して違和感を覚えたら「それは何をするものなのか」と確認をするようにして、すり合わせをしていくのが良いのかも。:+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802512966309249035) - > P.210 輸送業務管理アプリケーションでは、一連の荷積みと荷降ろしをすべて、それぞれの貨物取扱業務が行われた日付と一緒に提供できるようになります。あなたの言う「輸送日程」ですね - あなたの言う〜〜 という翻訳が入る時点で何か言語が分断されているサインな気がする:+1::+1::+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802511296099647509) - :memo: アンジャッシュ状態になると悲惨そう(そこまでいったことはないけど - :memo: 「客は自分が本当に欲しいものを知らない」という格言があるので、提示したモデルが誰からも理解されないパターンがある可能性がある。 - > この輸送日程が、本当は予約と輸送業務のリンクになっているんですね - p.210 - このひらめきは、まさに注意が「予約」「輸送」の間を行き来した(「輸送」だけに注意が固定されなかった)からこそ、得られたもののように見える:+1: - エキスパート(とみなされた人)との会話を、単なる会話でなく、(暗黙知の作用へつながるような)注意の移動を促す要素として見ることもできるのでは - そう考えるなら、エキスパート(とみなされた人)との会話で重要なのは、いわゆる「要件」「業務」の知識を収集するだけでなく、注意の向き先を様々に移動させる点にもある、とも言えそう:+1: :+1: - すなわち、エキスパート(とみなされた人)との会話においては、単に相手の言葉を聞いてその定義を把握する(部分に注意する)だけでなく、それらの情報を行き来しながらいかに全体をつなげる or つなげないか(注意の移動 -> 暗黙知による統合)を考えることも重要、とまとめることもできるのでは:+1::+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802507752303755285) - :memo: 特定の領域をピンポイントに見るのではなく、他にも目まぐるしく注意を向ける、かぁ - :memo: 暗黙知で回っている業務を下手に部分に注目してモデル化して型にはめてしまうと、業務がうまくまわらなくなってしまう=ゲシュタルト崩壊? - :memo: 確かにモデルの真の正体を探るとき、関係するモデルや背景とか意図とかいろんなことを同時に把握しようとするから、むちゃくちゃエネルギーを使う。 - 予約アプリケーションにある輸送日程帳票から、「輸送日程」を確認して、次にやるべき荷役作業の計画を立てる。その中に、荷受け地、荷出し地や日付があるということなのかな。あくまで例題の会話なのでわからないけど、既存の業務フローから整理していたら、また発見の流れは違ったような気がする。 ### ぎこちなさを精査する - > ある開発者は、次第に利息計算が複雑になっていくことに悩んでいた。彼女はこの状況について、より利息計算に適したモデルを見つける好機なのではないかと思い始めた。 - ある手続きの達成が大変になってきた時に、それを技術的な観点のみ(プログラムの分割や再配置など)で解決しようとするのではなく、そもそも解決モデル(=ドメインモデル)の再検討へと立ち返るあたり、モデル駆動的 - 技術的な観点も重要ではある。それが無いと、実現不可能な解決モデルを作ってしまう危険も。 - 「○○**のみ**ではない」というのが重要なのかなと。いろんな観点を渡り歩く、渡り歩こうとする態度。特定の目線への「[居着き](https://t.co/tAlAPGAlbR?amp=1)」を避ける。:+1::+1: - > 「居着き」の撤回。つまり、決意を一点に集めて駆動力にするのではなく、分散する事で異質の機動力を瞬時に創造せよと提案しています。まずは「型」を求めない。 - 発生主義会計のことをちゃんと認識していなかった。 - https://www.noc-net.co.jp/blog/2016/02/column_110/ - 利息計算と、支払いはまた別のタイミングで元帳に記帳される ### 矛盾について熟考する - 矛盾について熟考するのは、条件つきの場合があったりとか、誤解している可能性とかもあるので、非常に有益だと思った:+1::+1: - 大体その矛盾に気づく時って、後から(実装する時など)になることが多かったりするけど。:+1: - P.218「そういう厄介な矛盾は~略~より深いモデルへの大きな手掛かりになり得る」矛盾の発見はチャンスですね。:+1::+1: - 矛盾に見えるものは、実際に矛盾しているのか。実はもっとメタな or 異なる視点から見ると矛盾なく整合できるということもあり。例として出されている慣性の法則を発見する話なんかは、まさにという感じ。 - ↑の意味で、「矛盾」に出会ったら、一度判断を保留して「矛盾のようなもの」として扱い、それは本当に「矛盾」なのか?と問うてみるのも大事そう ### 文献を読む - 基本的な概念を解説しているの文献を読んだりするのは大事で、その上で現場で使われている同じ概念と照らし合わせて差異が無いか探るのは重要だと感じた:+1::+1: - > P.220 それでも、この開発者は調べた知識によって的確な質問をすることができたので、それがわかってからは、エキスパートも注意深く彼女の話を聞き、彼女の質問にはすぐに解答できるよう、特別に努力したのだ。 - ドメイン知識を掘り下げるだけに限らず、ある事柄について知識を蓄えて質問を溜めておくのは、必要なことだと思っている:+1::+1::+1::+1::+1::+1: - エキスパートの信頼を勝ち取ることが大事ですね - > 『アナリシスパターン』(Fowler 1997)の第6章 - 「在庫管理と会計」の章。勘定・トランザクション(おそらく”金融取引”の意)・エントリ・転記ルールが、重要概念として挙げられている。 ### 何度でも挑戦する事 - > P.221 設計における誤りを避けようとすれば、結果としてできるものの品質は低くなる。基になる経験が少ないからだ。しかも、簡単な実験を連続して行うよりも時間がかかりかねない - 本書の冒頭で言っていたアジャイルを前提としているのは、こういった考えがあるのだろうと思った。:+1::+1::+1::+1::+1: - P.221 「何度でも挑戦する事」によってモデルに深い洞察が埋め込まれていく。かつ、曲げる必要があるときに曲げられるものになっていく。最初から完全なものでなければならないのではなく、繰り返し繰り返し洞察を深めて育て上げていくものがモデルなんですね。 ## 疑問 - 本書では「設計のぎこちなさ」と表現することが多いけど、「ぎこちなさ」ってどういう感覚だろう? どういう時にぎこちなさを感じるだろう?:+1::+1::+1::+1::+1::+1: - ロジックの置き場所に悩んだりとか、名付けに悩んだりとか、がありそうかな?:+1: - 声に出してモデリングしたとき(P.30)、言い回しがややこしくなるとか? - いちいち補足説明が必要なもの。且つ「え?そんなクラス名と意味が違うやん、そんな意味含まれてないやん」と驚くような感じ。 - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802504429517537290) - :memo: におい、というやつですね - :memo: 例えば、要件は満たせているけれど、整合性を表現しようとすると過剰に複雑だったり表現しにくかったりすると感じるときとか。 - :memo: 明らかに変化しやすそうなところが、固定的な設計になっているときとか……は、ぎこちなさというよりも不安さかな。 - :memo: 複雑でしかも役に立ってないのにイビツさを感じる。 --- # それほど明白でない概念をモデル化する方法 ## 目安の時間 - 30分 ## 感想・気づき - 3つのカテゴリって、「明示的な制約」、「ドメインオブジェクトとしてのプロセス」、「仕様」ということかな。 ### 明示的な制約 - 制約を独立するメソッドに分解する。埋もれてる制約をメソッドに切り出して明示的にするのはよく行うリファクタリングかも。 - オブジェクトに切り出している例9.4の図、メソッドに切り出すよりもかなり視覚的にわかりやすい。「運行と貨物の間の関連にはオーバーブッキングポリシーがある」と言葉にもしやすい。:+1::+1: :+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802517682201165864) - 制約を実装するオブジェクトの設計が、制約によって歪められることの警告の中で、3番目の「実装では制約が手続き型のコードの中に隠れてしまっている」というのはよくあるーって思って読んでいた。 - if文、switch文が乱雑になっているのは、警告のサインなのかもしれない。:+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802514980032217088) - > 制約によってオブジェクトの基本的責務があいまいになっている場合、あるいは、制約がドメインではっきりと見てとれるのにモデルではそうでない場合、制約を括り出して明示的に1オブジェクトのにするか、オブジェクトの集まりとそれらの関係性としてモデル化しても良い - 個人的には、メソッド化よりもむしろこちらをよく使う印象:+1: - 制約が課されるオブジェクト単独で完結するケースに、あんまり遭遇しない - オブジェクト単独で全く完結する場合は、その内で終わらせるけれど - オブジェクト単独で完結するように見えても、結局「○○の場合にはXXだが、△△のときにはYYという制約も必要(あるいはXXは不要)」というケースがあったり:+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802519749983862804) - 制約をクラスやメソッドで切り出せるとユニットテストもしやすくなっていくからリファクタリングも進むと感じた:+1::+1::+1::+1::+1::+1: - > 制約とプロセスは、オブジェクト指向言語でプログラミングしている時にすぐには思い浮かばない、2大モデル概念である - プロセスのオブジェクト化については、GoFのパターンでもCommandパターンとかStrategyとかを知っていれば、発想のヒントに一応なりそうな気もする - 両者とも、つまりは一つの手続き(プロセス)自体をオブジェクト化して、何かしらの処理(選択、redo、undo、chain、etc...)の対象(=オブジェクト)にすることを可能にする(したい時の)方法、という理解:+1: ### ドメインオブジェクトとしてのプロセス - P.224「ドメインオブジェクトとしてのプロセス」手続き的な記述になっている部分をカプセル化して整理する事で、目的や意図が見えやすくなり、概念が明確になっていく? - ぎこちない部分のリファクタリングが、隠れている概念を浮き彫りにする。:+1::+1: - > P.225 明示すべきプロセスと隠蔽すべきプロセスを区別する鍵は簡単だ。 - 明示するというのは、ドメインモデルとして明示しない、ということで良いのかな。隠蔽するプロセスも普通に型やメソッドにすると思うし。 - > 私はこの仕様をMartin Fowlerと共同で開発した(Evans and Fowler 1997) - 多分原典 -> https://www.martinfowler.com/apsupp/spec.pdf ## 疑問 - > p.225 制約とプロセスは、オブジェクト指向言語でプログラミングしている時にすぐには思い浮かばない、2大モデル概念である - これらについて、「確かに思い浮かばない」という実感をもつ人と「むしろ普段から考える」という実感をもつ人と、それぞれどのぐらいいるのだろう - [discord](https://discord.com/channels/432531367427964929/740202765619429487/802521130375184406) --- # ======後半(2/6)はここから======== # Discord開始位置 - # 仕様 ## 目安の時間 - 20分 ## 感想・気づき - ルールが複雑な場合は、単純な仕様(ルール)に分けて、論理演算子で結合して表現したものを、さらにメソッドにするような感じかな。 - 複雑なルールをあるオブジェクトの中のルールにするのではなく、明示的に評価するものをオブジェクトとして独立させるほうが、意図が伝わるということなのかなと感じた。:+1::+1::+1: - P.228「仕様は、他のオブジェクトの状態に関する制約を述べる」:+1: - 生成に関する関心毎をファクトリに切り出すように、オブジェクトに関するルールを仕様として別クラスに切り出す事感じ? :+1::+1::+1: - 重複したコードから、「これは共通したルールなんだな」と気付き、別メソッドに切り出すことはあった。が、ドメイン観点から「これは業務上のルールだ」と意図的に分けたことは無かったように思う。ドメイン観点からのアンテナも貼ることで、暗黙的な概念の掘り出しを行いやすくなるかもしれない。:+1::+1::+1: - 正直、仕様をわざわざクラスに分けるまでの必要性を感じたことがないのが本音(やった方が良いと言われればその通りだと思うが)。DDDのパターンの中でも、仕様はそこまで普及されていないイメージがあるが、同じように感じてる人が多いのかな?ある集約にのみ必要なルールであれば、その中に留めるだけで事足りている印象。集約が肥大化したり、ルールの範囲が1集約にとどまらない場合になって初めて必要性を感じてきそう。 - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807577280917536778) - ルールが複雑な場合は、埋没しないように分離したくなる。:+1::+1: - また、業務上、ルールが変化しやすい場合も、ルールだけ変更すれば済むように分離したくなる。:+1: - 複数のオブジェクトで (部分的な重複も含め) 共通した仕様を必要とする場合も、分離されている方が扱いやすい。:+1::+1::+1: - 複雑な仕様の場合、一つの大きな「手続き」としてではなく、分解・組み合わせ可能なルールの集合として作りたくなることがある。その場合に、仕様オブジェクトは強力 :+1::+1::+1::+1::+1::+1::+1: - 小さなルールの集合で複雑なルールを作るイメージ:+1: - 状況に応じてルールの組み合わせを変えたい、という場合には、さらに上位の「ポリシー」を作る場合も。:+1: - 現場で役立つシステム設計の原則でもありましたね。 - 似て非なるルールが多いときにルール部分を切り出してストラテジなんかと組み合わせると使い勝手良いかも。 - 「暗黙的な概念を明示的にする」という章の一節として書かれているのも、ポイントだと思う:+1::+1::+1::+1::+1: - 「暗黙的な概念を明示的にする」ための方法として、「暗黙的な概念」をそもそもオブジェクトとして独立操作可能にしてしまうアプローチ ## 疑問 - *ドメインサービス*と*仕様*の違いが気になった。:+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807573169649090590) - *ドメインサービス*の方が広い概念で*仕様*はより限定されたもの?(*仕様*は*ドメインサービス*の部分集合みたいな?) - ドメインサービスは処理に重きが置かれていて、仕様はルールに重きが置かれているイメージでした。 - 仕様は値オブジェクトです。 :+1::+1::+1::+1::+1::+1: - 仕様オブジェクトは、ドメインサービス他ドメインオブジェクトを実装するための部品的な位置付け :+1::+1: - 仕様オブジェクトは個別かつ組み合わせ可能なルールの表現が、ドメインサービスは一連となる手続きの表現が、それぞれ役割というイメージ:+1: :+1: - 仕様の版管理したりするとエンティティにもなり得るのだろうか。 # 仕様の適用と実装 ## 目安の時間 - 20分 ## 感想・気づき - > p.229 仕様の価値の多くは、全く異なるように見えるアプリケーションの機能を統一することにある。……検証、選択、要求に応じた構築という、これら3つの用途は、概念レベルでは同じものである - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807581973153054720) - 仕様を述語的な値オブジェクトとして纏めておくことによって、手続きの中にルールが埋もれるのを防いでいるのか。:+1: :+1::+1::+1::+1::+1::+1: - 現状、以下の理解 - 検証→すでに作られたオブジェクトに対して、検査をする - 選択(もしくは問い合わせ)→ある条件に一致したものを抽出する、Select的な使い方 - 要求に応じた構築(生成)→仕様に合致したもののみ生成する - P.234〜P.236の例は、インフラストラクチャのフレームワークの力が借りられない場合のコード例 - P.234〜P.236の例をみると、改めて実装が技術的な詳細に引っ張られることがわかる。モデル駆動設計を強く意識しないとたちまちドメインモデルがSQL文まみれになったり、リポジトリにドメイン知識を書くことになってしまうと感じた。 - P.238のジェネレータのインタフェースを記述的な仕様の形で定義するメリットで、入力で渡した仕様を出力されたオブジェクトが満たしているか「検証」をすることが可能、と書かれていて、なるほどと思った。:+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807582961770823680) - :memo: テスタビリティー上がる - :memo: ルールだけ検証したい、っていう場面は、実際に多々ありますものね。 - :memo: 仕様をオブジェクトにしておくと、仕様の方のテストも簡単になりますけど、仕様を使う側のほうのテストも簡単になりますよね。仕様がOKの場合のフローのテストや、NGの場合のテストを、モック仕様オブジェクトを注入してやれば良くなるので。 ## 疑問 - > P.238 仕様を用いなくても、ジェネレータを書いて、そこに必要なオブジェクトを生成する手続きか命令一式を与えることができる - いきなりジェネレータって言葉が出てきたけど、ファクトリのことでいいのかな? それとももっと一般的な用語なんだろうか:+1: - 複雑な集約の生成条件を隠蔽するのがファクトリだったが、仕様(生成)との違いをイマイチ理解できていない。構築に関するロジック全般を記載するのがファクトリで、そこに業務上のルールが存在すれば仕様に置き、ファクトリから利用する?:+1::+1::+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807580087557554198) - ファクトリは生成する手順も含めたもの - 仕様オブジェクトは判断されるルールだけを表現したもので、ファクトリでも使えるし、他の物でも使える --- # 例9.5 化学製品倉庫での格納 ## 目安の時間 - 20分 ## 感想・気づき - 例えば仕様という概念を発見してない(もしくは明示的に使っていない)としたら、こんな感じのモデルになるんだろうか。ルールが吹き出しなど、補足として書かれていることになりそう。 :+1::+1: ![](https://i.imgur.com/6i9VYzY.png) - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807585343108415499) - :memo: p.239の図の「化学薬品 → コンテナ仕様」という依存関係とかもコンテナに吸収されるので、オブジェクト間の依存関係がもっと絡み合うでしょう。 - :memo: 「Aに関するルールだから」と全部Aに詰め込むと、依存関係が奇々怪々になったりメソッドが膨大になったりして、だいたい悲惨になりがち ## 疑問 --- # 例9.6 倉庫内格納サービスの、実際に動作するプロトタイプ ## 目安の時間 - 20分 ## 感想・気づき - プロトタイプ格納サービスのfindContainerFor()がやっていることは、仕様の適用であった選択(もしくは問い合わせ)だとわかった - 例9.5は格納サービスを作るチームのお話で、例9.6はそれを実際に使うアプリケーションチームのお話っぽい - 仕様とモデルに基づいて定義した格納サービスのインタフェースを使って、実装詳細はまだ詰められてないけど、他のチームとの協業は進められる - APIスキーマを定義しておいて、そこから開発するみたいな ## 疑問 - 他チームとやりとりするようなインタフェースの定義ってどのタイミングでするか。今回の格納サービスは、コンテナとドラム缶の中に、コンテナ仕様があると考えられた仕様だけど、それが途中で変わるのは十分有り得りそう。その時に、インタフェース変更で大きな影響は起きそうだなぁと。:+1::+1::+1: :+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807590096953933854) - :memo: (もう少し先の14章当たりでもこのあたりの話題で出てくるかも。境界付けられたコンテキスト間でのモデルの整合性の維持の話。 - ドラム缶同士のインタラクションが必要になったら、この例からどのような形に改修していくと良いだろう? :+1: - [discord](https://discord.com/channels/432531367427964929/740202765619429487/807593237556232232) ---

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully