2016/12/09に第二回DDD座談会があります!!
第二回DDD座談会(https://ddd-zk.connpass.com/event/43587/)
2016/06/05(日)に開催された 第一回DDD座談会 の談話録です。
http://ddd-zk.connpass.com/event/31842/
Twitterのまとめはコチラ
第一回DDD座談会(http://togetter.com/li/985002)
オフレコかなと思う個所は除いておりますが、それ以外に訂正ございましたら、ご指摘宜しくお願いします。
<(_ _)>
オープニング
高江洲さん(@takaesu0)
みなさん、こんにちは 。
今日はDDD座談会の1回目。実践者が集まり、DDDについて話し合う会です。
私は本日のモデレータを務めさせて頂く高江洲です。宜しくお願いします。
DDDとの出会い自体は古く、JavaEE勉強会にDDD読書会がありまして、そこでのちに翻訳する和智さんと出会ったり、devtesting-jaで高木さんと出会ったりしていました。
DDD座談会の発端は、4月某日某所で座談会を行ったのですが、これをクローズドで行うにはもったいない、公開イベントでやりたいよねという話で盛り上り、今日の開催となりました。
DDD実践者を集めて、普段のセミナーではなかなか得にくい知見を共有したり、質問したりする、会場の皆さんと作る座談会形式のイベントです。
基本は、登壇者が事前アンケートから気になる話を好き勝手に話します。
会場からの乱入も大歓迎ですので、俺に喋らせろとマイク奪ってもらってもいいでし、どんどん前に来てください。
いい席用意していますよ。
登壇者紹介
増田亨さん(@masuda220)
増田といいます。ドメイン駆動設計については、自分なりに、それなりにやっています。
どっちかというと一方的にしゃべる事は行っていて、私の勉強会来た人はご存じだと思いますが、殆ど時間オーバーして、質疑の時間取れないので、今日はぞんぶんに質疑を受けたいと思います。
今日はみなさんと情報共有できたらいいなーと思ってます。
最近注目しているのは、DDD本読んでから10年ぐらい経っているのですが、原点回帰っぽくなってきていて、ソフトウェア設計って変更容易性大事だよねって。
そして、変更容易性を突き詰めていったら、今度はモジュール性だよねっとか・・。
モジュール性は、手続型のモジュール性とオブジェクト指向のモジュール性では全然異なっていて、変更容易性をモジュール性で突き詰めるのなら、オブジェクト指向だよねっと。
今はそういう原点回帰という所にはまり込んでいます。
末並さん(@a_suenami)
末並と申します。会社に何も言っていないので、今日は個人の意見です。
好きなモノは、データベース界隈だったり、OO界隈やDDD界隈にいます。
この登壇者の中では一番面倒くさく無いので、マイルドな返答が出来ると思います。
今日は、本から得られた知見を開発にどう活用するとか、チームビルディングにどう適応させていくとか、実装詳細がどうだとか、○○パターンや○○設計がなんやらという細かい話より、もう少し広い話をしたいと思っています。
仕事は女性向けメディアの開発を行っているのですが、
キュレーションメディア自体が世の中にも新しくて、ドメインエキスパートがそもそも居ないよと言った中でどうやって、設計を駆動させていくのかが、今興味ある処であり自分も色々と学びたいなと思っている処です。
最近は、糖質制限を2年近くやっておりまして、Twitterでラーメン・ごはん・寿司の写真が挙がると、「○○さん、それは糖質ですよ」とクソリプするのが日課です。
そこで「糖質警察」とあだ名をつけられまして、末並の前で糖質食べるとヤバい、取り締まられると言われたりしています。皆さんも僕の前で糖質食べると、クソリプが届くと思います。
原田さん(@haradakiro)
原田と言います。DDDとの出会いは、本(原書)出版された直後に読んでこれは良いと思い、実際に2004年にはドメイン駆動っぽい開発を行いました。
DDDを行うと言っても、開発チームが100名も居るとなかなかシンドイのですよ。
プロトタイプで良い設計出来たとしても、某Sierに投げると"ぐちゃぐちゃ"になったモノが返ってくるのですよ。
これは違うなと思い、最近は開発チームをどうするのか、開発プロセスをどうするという話が多いです。
良いソフト作りたくて色々やっているのですが、変な事言うと、ソフトウェアは可愛くなくてはいけない。
大きいソフトウェアは、その時点で可愛くないです。
つまり動さの予想がつかないのは嫌です。
予想した通り、こうしたらコケるよねという所で予想通りコケるのが良くて、あとは、1つだけでも期待よりほんの少しだけ、気を利かした動きをしてくれるソフトウェアが好きです。
2004年にいれたソフトは可愛くて、導入した工場が死ぬまでまっとうしてくれました。
奥田佳享さん(@yoskhdia)
奥田です。よろしくおねがいします。
普通のSierから、ベンチャーに一年前転職しまして、株式会社Socketというところで働いています。
DDDをScalaでReactiveなシステムで行ったりしています。
あとは、プロダクトデザインや、SPAとかそういうところに興味があり、色々な勉強会に参加したりしています。
自己紹介どうしようかなと思ったのですが、本の紹介をしたら、その人なりが判るかなと思うので紹介していきます。
『ドメイン駆動設計』は、1週目はフンフンだったのが、2週目からはこんな深みがあったのかと気づきを多く得られました。
『ユースケース駆動実践ガイド』は、DDDにはプロセスは定義されていなくて、プラクティスが多いのですが、そのプロセスというところが、読んでいて良いなと思いました。
『メタ思考トレーニング』は、Whatで考えかちな事を、Whyで考えるという話なのですが、スゴク良かったです。
『カンバン仕事術』まだ読めてないのですが、後々感動する予定の本です。
これは紹介しても僕にインセンティブは入らないですw
かとじゅんさん(@j5ik2o)
ChatWorkで働いています。
『ChatWorkでScalaどうなったのですか?』って聞きたい人いますか?
ドメインでは、業務部分と技術の関心を分離したいのですが、あっという間にアクターの技術的言葉に圧倒されまして、ドメインロジック何処だ?という難しさがあるのですが、そこを上手く関心を分離する方法を、模索しながら仕事しております。
エリックが来日していたときに、TwitterのCTOが来ていたのですが、エリックがポロっと「TwitterとかはDDD合わないかもね」と言っているのを聞いてしまいまして、自分はまさにそのコンテキスト界隈にいるので、何か試されている感はあります。
今日は、議題は特に決まっていませんので、参加者が前に出て話してもらって全然良いので、盛り上がっていきたいと思います。
議題:DDDに向いている要件や費用対効果は?
参加者(議題提案者)
DDDをこの規模だったら採用しないとか、費用対効果・向き不向きとなど、色々判断基準はあると思うのですが、どのように判断されていますか?
また、DDDで投資を結構行ったのに、結末が悲しく終わったプロジェクトとかありましたか?
原田さん
いきなり7~8人に分けてから、DDDで開発を行うのは無理だと思います。
ユビキタス言語とかは、暗黙知を共有出来ているからこそ使えるものなので、暗黙知や、意思決定のやり方が共有されていることが、肝のような気がします。
増田さん
私が気にしているのは、ただ一点です。
『Build for Change』ソフトウェアを作る事が、変化していく事に繋がるのならば、DDDを行った方がいい。
しかし、現実問題としては、『Build for Not Change』という事もある。
その場合は、DDDではコスト回収出来ないと思っている。
だからこそ、逆にエンジニアならこういうモノにこそチャレンジしていって欲しいとは思っている。
奥田さん
1回システム作れば終わりというものではなく、成長させて行きたいものなのか、会社として継続的に投資していきたいプロジェクトなのかを気にします。
作って終わり、不変なシステムに対して、DDDは過剰かと思います。
かとじゅんさん
前はソーシャルゲームの会社にいまして、DDDの良さは判るし、小さく作ってビジネス変化に対応していこうという気負いはあったのですが、如何せん、アジャイルサムライが言う処の荒ぶる四天王が邪魔しまして・・・プロジェクトの性質上、納期に間に合う事が価値になると、そういう荷重がかかっている中で、DDDを行うのは酷で、モデルなんて考えている暇ない、ということも多々ありました。
こういう時は、ドメインビジョン宣言文「このドメインは何を目指しているのか説明出来る事」が大事なのだと思います。
何をやっていいのか、悪いのかが明確にできます。
ドメインビジョン声明文と経営戦略が合致すれば、作ったものは経営戦略の一部を支えていくことになるので、こういう事にDDDは有効だなと最近は思っています。
末並さん
僕の場合は、あまりDDD実践していないので、DDD採用しましょうという事はなく、この部分はDDDのエッセンス取り入れて開発してみたりなどの考えで見ています。
その中で、その概念や機能などが、会社やプロジェクトにとってどれぐらい大事にされているのかという点を気にしています。
プロジェクト単位より小さい機能単位で見て、3ヵ月、半年経てユビキタス言語になりそうな場合は、その言葉は大事にしましょうとか、その機能で使われている仕様などは、単語レベルで気を使って定義しましょうとか考えています。
実装するだけで月の売り上げが●千万というのは間違っては無いのですが、その機能で数年食べていこうと考えているのなら、数週間で捨てる言葉でなくて、育てていかないといけない言葉になると思います。
その場合、コストは2~3年かけて回収していくと思います。
議題:開発途中から、DDD始められますか?
原田さん
スマフォのゲームを例にすると、まずさっさと作ってリリースして、半年後にまだゲームが生き残っていたら、DDDを始めていいと思います。恐らく10%も生き残っていないはずです。
どこまで長生きするかなんて事前には読めないので、ある程度の期間を生き残った機能については、まじめにメンテするのが良いかも思います。
そうすれば、全部モデリングしてからでないといけないという、Big Design Up Front(BDUF)という地獄の罠に、はまらずに済むと思います。
奥田さん
もともとRailsで作っていて、もう少し静的片付け言語だったら、リプレイス楽だったかなと思う時はあります。
増田さん
私が関わるプロジェクトは2種類しかなくて、自分達の自由にできるプロジェクトか、どうしようもなく火を噴きまくっていて何でもいいからどうにかしてくれというプロジェクトのどちらかです。
動いているシステムを変えるというのは、コストだったりリスクになるので、よっぽどでない限り、出来ないのかなと思ってます。
議題:(Twitterから)途中からDDD初めて作り替えていく場合、やっつけで作った個所をどうやって差し替えていくのですか?
原田さん
テスト出来る範囲、インターフェース差し込む部分、データ突っ込める部分、だけは気を付けるようにしています。
やり方は、新旧システム双方にデータ食わせて、両方から同じデータが出てくることを確認してから、並列で走らせて切り替えます。ストラングラー絞め殺し戦略(「ストラングラーアプリケーション」)と言うのですが、アプリケーションの外に同じ動きするアプリケーション用意して、同じデータ出力を確認できたら絞め殺す、ようはシステム切り替えるという方法です。
かとじゅんさん
Twitterからですが、「Railsでやっつけで作ったものは作り直しになりそう」とあります。
原田さん
Railsはね、データベースのViewをModelというところに書いている処がダメですね。
・・・ということを、今日は言い合う会で良いんだよね(笑)。
末並さん
Railsに、DDDをそのまま適応可能かと言われると、難しいかなと思っています。
僕は仕様の中でのユビキタス言語発見の仕方と、それを如何にActiveRecordを中心としたシステムに取り込むか、そこまでかなっと思ってます。
かとじゅんさん
使えるものは、部分的にでも取り入れるという感じですよね。
議題:DDDを採用して後悔したこと、失敗したことは?
増田さん
同じお客様のシステムを何年も担当させて頂いているのですが、作った当時、納期などでおざなりになっていた箇所を改修する度に、もっと頑張っておけば良かっと思う事が多いですね。
しかし、DDD的設計・開発でのチャレンジに対して、Goを出したりストップしたりする判断を、お客様が行うには非常に難しい訳で、どこまで行うのかというのは、お互い納得できるまでやるしかないのかなと思っています。
あと、失敗したんだろうなというプロジェクトは見たことあります。
DDDやっているという割には、ドキュメントばっかり書いていたりなど。
書いたコードのフィードバックを、それなりの重さを得てやらないプロジェクトは失敗するだろうと思います。
原田さん
開発現場のコーチとか、コンサルとか生業にしているので、すげー上手く行っている現場には、基本呼んで貰えません(笑)。
現場に行ってみると、色々なものがやり玉に挙がっておりまして、スクラムが駄目だ、DDDが駄目だ、関数型は早すぎた・・・
単純な話、練習していないのですよ。練習しなくていきなり行ったら、失敗しますよ。練習のつもりで三カ月やってみて下さい。なにを間違えた?失敗した?次に直すなら何処?
誰も経験者いない状況で、『スクラムは生産性高いって言ったじゃん』と言われても、練習しなくても出来るなんて、一言も言ったことない訳で。
そういう意味では、DDDも新しい事がいっぱいあるので、まずは課題授業プロジェクト・週末プロジェクトでDDD練習してみて、そこから本番プロジェクトで行ってください。
会場参加者
Pythonで開発していたのですが、Readリクエストの変更や追加が発生すると、リポジトリのインターフェースの追加や実装の変更発生など、ちょっとの変更でも、4~5か所変更対応しなくてはならなくなってしまい、リポジトリが煩雑になるほど、チームが疲弊してしまったのですが、今思うと、Readリクエストの実装で律儀にDDDを遵守するのではなく、早く結果返せばいいだけで、DDD適応はもっと、ビジネスロジックに関わる処だけにしておけば、良かったなと思っています。
かとじゅんさん
そうですね。Readリクエストが複雑化するとリポジトリにFindBy●●みたいなメソッドやら何やらがドンドン増えてきて、僕も疲れてしまったことがあったのですが、今は、Writeモデルの変化に合わせてReadモデルを用意して、アプリケーションレイヤーでクライアントが求める形にコンバージョンするなんて事をやっていたりします。
この場合、Writeモデルはシンプルになるのですが、Readモデルは複数できるので、全体でみると複雑にはなっているのですが、単体ではシンプルになっています。
ようは複雑さを何処に寄せるのか、副作用が起きることにモデリング的にどういった価値があるのか考えていければいいのかなと思ってます。
議題:DDDを適応させる規模について
会場参加者(議題提案者)
自分の印象としては、開発規模が大きい方がDDDのメリットがだせると思っていまして、RailsやWEB系は、エンタープライズ系と比べると、比較的開発規模は小さく、ユビキタス言語とか、そんなに頑張らなくても開発できる気がしています。
大規模だと、合意を得るために、同じ言葉を使うことに注意していかないと、上手く行かないという印象があるので、DDDの効果があるのかなと思っています。
原田さん
折角なので反対意見を述べたいと思います(笑)
私は、DDDを小さくて短納期なシステムに使うのが大好きです。
小さいシステムは、機能一覧洗い出しに抜けがあると死んでしまうのですよ。
そこで、ドメイン対象のエンティティがどれだけいて、それに対してサービスがどれだけいます。
そういう見積もりの方が外しづらいです。
小さいシステムだと、その部分がコンテキストだという境界が判りやすくなり、結果として小さい部分を小さく作れると、大きいところも扱いやすくなります。
大規模で、全体で使えるユビキタス言語と言われると相当辛いのですが、小さいシステム範囲なら、開発チームとお客さんとでは、言語は通じ合えますので、そこから、じわじわ広げるほうが向いているのかなと思います。
会場参加者
何で規模を図るかによるかと思いますが、原田さんが今言われている規模は、開発者の人数なんでしょうか。
どんなに大きいシステムでも、使えない奴が混ざっていないという前提なら、少ない人数で開発した方が、良いものが早く出来るよとと言われている印象があるのですが。
原田さん
使えない奴を混ぜ無いのは無理なので、全員鍛えてしまえばいいだけの話です。
その場合、20人もいたら目配りするのは無理ですが、一桁人数なら全員コードレビュー出来ると思います。
ある現場での体験談なのですが、コーチングとしてコードレビューを毎週行っていたのですが、ある日、怒られてまして『コードレビューアーだけして、レビューインしていないやつがいる。お前だ!』と。。。
翌週、タスクを貰いまして、一生懸命コード書いてレビューしてもらいました。
会場参加者
ユビキタス言語でコミュニケーションとれて、それが修正できる人数でないと難しいという事でしょうか?
原田さん
最初はそうですね。それをじわじわと広げていきます。
あるプロジェクトでDDDで開発したとき、納品したらCMMIソフトウェア成熟度グループにコードレビューされたのですが、うちの開発は生産性が1/4で、バグ依存が倍だと言われました。
ちょっとムカついたので、比較対象のプロジェクト情報を頂きまして調べましたら、ユースケース当たりの行数が4倍ありまして、ようは4倍冗長だったのですよ。
1週間後、調査結果を報告しまして『共通ソース開いて展開すると、コード量4倍になって、生産性倍になって、
バグ密度半分になるけど、それをお望みですか?』そのままでいいですと納得いただけました。
そういう意味で、DDDで開発するとコードはコンパクトになると思います。
増田さん
私は、規模に関係なく、大きなモノを変えて行こうと思うのなら、是非DDDを行うべきだと思います。
『Do Code. Not Change』だったら、規模関係なく、全く無意味だと思います。
大規模でも本当に変えて行きたいと思っているのでしたら、チャレンジするべきだと思います。
コミュニケーション問題とか色々出てきて、大変だと思いますが、効果は期待できると思います。
末並さん
僕は大規模開発は関わった事ないので、想像半分になってしまうのですが、規模が大きくなってくると、アーキテクチャ側のインフラレイヤーや、UIレイヤなどを専門的に担当する人が増えていき、そういう人たちとのコミュニケーションコストを解消する為に、コンテキストマップや境界づけられたコンテキストなどが使われると思うのですが、それぞれが自分の担当範囲に固執してしまうと、コンテキストマップなどを適宜修正していくタイミングを逸して、実は複数ドメインで分けないといけないのに、単純に規模が大きくなっていく危険性があると思っています。
増田さん
たしかDDD本17章に、大規模開発で誰が戦略的な設計を行うのかという話があって、いくつかのチームが連携する際に、コードに責任を持てるリーダクラスが連携のコアを担当することで、上手く推進できると記載しているので、そこが大規模開発時でのポイントになるような気がします。
原田さん
アーキテクトは実装もする。実装できないのはアーキテクトじゃない。
議題:ユビキタス言語は日本語?英語
かとじゅんさん
こういう話は毎回出るのですが、毎回答えは無いで終わってます。
議題:全コンテキストに関係してくるオブジェクトの管理方法について
会場参加者(議題提案者)
ユーザやアカウントなど、どのコンテキストでも使用するものはどのように管理したらいいのでしょうか?
『ユーザID』は、どのコンテキストも利用するものなので、共通カーネルとしてどのコンテキストから利用できるようにするのか?
それとも、ユーザIDを持つユーザというエンティティを共通カーネルにするのか、または、各コンテキストごとに、ユーザIDというエンティティを作成するのか(要は共有しない)、どのように管理すればいいのでしょうか?
原田さん
まず最初に、ユーザはエンティティでは無いです。
アイデンティティとロールの話しになります。
つまり、アプリケーションがユーザをどうやって特定するのか、特定した相手にどのロール(権限)を与えるのかの話しなので、『ユーザ』そのもののモデルを持つ訳ではありません。少なくとも共通カーネルのエンティティではないです。
会場参加者その1
自分は、アカウント管理のドメインにおいて、ユーザIDはエンティティとして管理しておいて、他コンテキストから参照されるときは、値オブジェクトのようにふるまうよう使用しています。
会場参加者その2(上とは別の方)
スマフォゲーム開発を行っているのですが、ユーザというのがゲーム全般どこでも参照が必要で、様々なデータと紐づける必要があります。
場合によると言われるとその通りなのですが、共有カーネルとして1ヵ所に置いておいた方がいいのか、参照元各コンテキストごとに、ユーザを用意したほうがいいのか、ここら辺がモヤモヤしていて、はっきりさせたいです。
かとじゅんさん
チャットワークでも、ユーザを管理者や参加者などと呼んでおります。
チャット部屋に参加していれば「参加者」ですが、そのうえ「管理者」は部屋の設定変更が行えます。
同じ「参加者」でもコンテキストによっては振る舞いが変わります。
ユーザやアカウントという言葉で見ると、エンジニアはユーザアカウントとして認識しますが、銀行員の場合、銀行口座と意識しているかもしれません。他業界になれば、全く異なる認識をしている可能性もあります。
ユーザやアカウントという言葉が、そのコンテキストにとって意味があるのかが大事だと思います。
ユーザというモデルだけが先に来て、そこからコンテキストをどう分けるのか考えるのではなく、コンテキストを整理したうえでユーザというモデルが生息していて、別コンテキストに分けていくやり方のほうが、迷わない進め方だと思います。
奥田さん
コンテキストは、「意味が閉じる境界線」「将来に渡って同じ意味であり続ける境界線」のイメージで考えています。
DCIのようにデータと振舞を分けるアプローチを出来ないものかと思います。
コンテキスト同士が重なりあう部分のデータは、共有で使用せず、個別使用するほうが、変更対応しやすいと思いますが如何でしょうか。
かとじゅんさん
DDDではコンテキストがあって、同じ名前であってもモデルとして異なるから別けましょうという話がありますが、DCIでは本来一つのモデルだから、別けるべきではないという発想だと思っています。
原田さん
DCIはコンテキストを区切って、コンテキストマップで間を繋げと言っているのですが、ユーザでいうと、システムに対する権限を付与する対象、課金としての対象など、コンテキストは多数重なりあっていて、コンテキストは完全に切り分けられるものでは無く、重複する部分は存在します。
無邪気にコンテキスト別けて、コンテキストマップで繋げるという簡単な話ではないです。
DCI陣営はその難問に果敢にも挑戦する気で、当初Rubyで取りかかっていたのですが、オブジェクトにメソッド付けた後、そのメソッドを外せないという事が判明したので、今はコンテキストから外れたら、メソッドを外せる言語を作ろうとしているみたいです。
増田さん
共有カーネルについて、色々アプリケーションをまたがっているものを、共有カーネルに集約して、とことんそこにアプリケーションを依存させることに価値が出てくるのならそうすべきと思いますが、意味がないのであればやらない方が良いです。
共有できそうだから共有カーネルを使うというのは違うと思います。
コンテキストが異なるという事がハッキリしてくるのなら、「凝集したメカニズム」や「オープンホスト」など、認証の仕組みだけを共通化する方向に頑張って、共有カーネルとは異なるアプローチで対応するのが良いのかなと思います。
末並さん
私は、コンテキスト依存の振る舞いは、コンテキストとロールの組み合わせに押し込むのが設計指針として好きなのですが、如何せんRalsでそれを行うのが難しく、パフォーマンスが出なくアプリケーションの性能が悪くなっていきます。
原田さん言われた通り、コンテキストから離れたときにメソッドを外すという事を諦めれば少々まともになるので、だいたいそこで甘んじて設計しています。
ユーザの話しに関して、広告アドテクの話しをしますと、広告はユーザをUndefine(未定義)にする方法が色々ありまして、iPhoneでダウンロードしたユーザ、Andoridでダウンロードしたユーザが、未ログイン状態でWEBアクセスしてきたら、その時に識別用IDは発行してしまいます。
結果、同一人物に4~5個ぐらいIDが割り当てられている状態になります。
広告配信システムとしは、同一人物には同じ広告を配信したいので、IDをマッピングしていくのですが、マルチデバイス全盛の時代になるにつれて、ユーザというIDに様々なIDをマッピングしていく状況がはたして良いのか、根本的にユーザの定義自体から見直さないといけない時期に来ているのだと思います。
参加者に紛れていた(都元ダイスケ (@daisuke_m))さん
最近、OpenID Connectやアイデンティティの話しを深堀していまして、あるサービスが複数マイクロサービスのように別れている場合、マイクロサービスそれぞれがユーザ認識したいのですけど、ユーザのアイデンティティをツイッターIDとした場合、ツイッターIDすべてをユーザと見なすのか?未ツイッターユーザをいつユーザ登録してもらうのか?考え出すと結構大変です。
1つの方法として、システムが人のアイデンティティとして認識した何らかをエンティティとすることで、それに対して、コンテキスト変わると書き込みをする能力を付与したり、また別の関連エンティティが出てきたりするようなモデリングもあるのかなと、まとまっていませんが思ったりしています。
原田さん
今のシステムは、ログインする前からトラッキングしてますよね。情報を辿っていくことで、個人を特定していく。
これはユーザFactoryからは作れず、アクセスしたという記録の集計結果を解析することで得られます。
そう考えると、作り方は色々変わるだろうと思います。
議題:結果整合性を重視する設計では、UI設計が難しくなりませんか?
かとじゅんさん
質問意図が判らないのですが、非同期におけるUI設計が難しいという意味でしょうかね?
DDDにおいて、集約は整合性を維持する単位であり、集約の外側は結果整合性になるはずなんですよ。
Event駆動型のアーキテクチャーって非同期が多く、メソッドみたいに呼んだら終わるまで、Callスタックが終わってから戻ってくるまでではなくて、Fire&Forgetなので、Fireしたら忘れてしまって、相手側から戻り値が有る場合は、またイベント通知が来る特徴があります。
僕はCQRSでEventソーシングしているのですが、Actorに対してコマンド投げて
コマンドのレスポンスがまたActorにもどるのですが、イベントジャーナルとして保存されていくのですね。
Actorは1つのスレッドで決められたメッセージ数しか処理しないので、そのスレッド内では同期的に処理されます。
マイクロサービスアーキテクチャーにも書かれているらしいのですが、ジャーナルされたイベントを他のシステムが読み込んで何かする、他サブシステムでメッセージングしたりとか、CQRSのリードモデルを構築したりとか、RDBMSのトランザクション張って書き込みをしたりします。
ただし、それを行う場合、集約と同じようなWriteとReadモデル、Write側はジャーナルになっているが、Read側はテーブルになっています。それがRead Modelが複数の集約を結合したようなDTO形式ではなく、集約単位のテーブルかとだと、集約の結果整合性というのがテーブル書き込み時まで引きずられるので、そこは非同期ではなく、発生したイベント列ごとに書き込んでいかないといけなくなります。
あくまでも集約を受けるActorの不変条件は絶対に破られてはいけない、これはほかの場面でも同じですよね。
つまりドメインモデルは絶対壊れてはいけないという考え方になるのかなという事です。
原田さん
理想はそうなんですけど、現実は業務アプリでそういう状態をつくらないといけない時がある。
私は生産管理屋さんなので、生産管理系アプリが多いのですが、そのときUIとなるのは「出荷」ではないのですね。
トランザクション出荷というのはシステムはもはや起こせないので、「出荷依頼」になるのですね。
出荷のリクエスト送ります。非同期でリクエスト処理しましたと通知が帰ってきます。
通知は、websocketでうけるなり、JSONで受けるなりで処理しましたと、画面に表示できるわけですよ。
昔は『Don't ask Just Tell(相手オブジェクトをちょくちょく見るな、いいからやりたいことを言え)』だったんですね。
でも、今は作り方変わってきていて、『Don't Tell Just Request(お願い)』
今はやりたいことを直接言えるかわからない訳で、上手くいったときは願いは叶えられたと返ってくる事があるし、そんなん知らんしって言われる時もある。そもそも無のつぶてという時や、送られていなかった時もある。
そういう時は聞き直せばいいということなので、そうやっておくことで、システム全部のサービス稼働を99.9999・・・にしておかないと、システムが正しく動かないよという事態を避けつつ、割と普通はいい感じにリクエストが返ってくることができる状態にすることができる。
かとじゅんさん
そういう意味では原田さんと非同期の境界線が違うのかと思う。
I.Oの境界というのは、その一つの集約でシーケンシャルにイベントが起こったら反映されなくてはならないという話ですけど、言われた通り、書き込みは読み込めるようになってから、書き込み完了を返すというのは僕らも行っていなくて、書き込みを受け付けましたとだけレスポンスだけ返してます。
あとは、リードモデルが完了したら、先ほどWebSocketと言われていましたが、HTTPのストリーミングで非同期で返すことあるし、ポーリング出来たらまだ完了してないよと返すこともあります。
そんな感じで僕らもやっています。
奥田さん
僕が思ったのは、UIの通知が難しいという質問について、失敗と言っても色々な失敗があると思っています。
例えば、「登録に失敗しました」というのなら、後で受け取っても良いと思いますが、その一方で出荷や在庫確保が出来ていないのに次の荷物の処理を行ってはいけないと思います。
失敗による大きさ・影響度があるのかなと思います。
前者はポーリングとかで良いと思いますし、後者はサーバサイドの方にリダイレクトをかけて整合性を保つとなるとおもうので、そういう難しさというのはあると思うので、質問意図をもう少し知りたかったかなと思いました
参加者
私は質問者ではないのですが、結果整合性の例えで在庫の話がでましたが、在庫みたいに量に限定があって非同期で複数同時引き当て要求がある場合だと、Atomicで行うのならば、今まで通りの考え方で分かるのですが、結果整合性になると、引き当てできたのか、ダメなのかいつ判るのかも分からないし、結果が判明した時に、運用やプロセス的にヤバいのかどうなのか、その辺がどう処理できるのか知りたいです。
かとじゅんさん
それは、すごく難しいと思っていまして、業務プロセス上、不正な状態が観測できてはいけないのに、結果整合性にしたために観測できてしまい、ビジネスワーク上に流れてしまって、人が流れてしまうことですよね。
原田さん
(マサカリ)なげていい?
Atomicなものがある在庫システムを作るのは素人です。それは作り方が間違っています。
物流システムはフローのシステムで作らないといけなくて、Atomic Ropeがあるというのは、ストックのシステムとして作っているからです。
それは結果なんです。
フローが出たかどうかなんて、現品引き当てているので、システムレベルではAtomicなんていらないんですよ。
在庫システムでAtomic Ropeがいるというのは、どこかに設計ミスしています。
現在庫量は計算量なんですよ。
まぁ、こういう細かい話はどっかで話しましょう
かとじゅんさん
結果整合性という話で、例えばですがチャットワークもチャットルームを作るときに、「部屋」と「管理者」と「メッセージ」を1つの集約ではなくて、3つの別々の集約にすると結果整合性になりますが、
ビジネス上、管理者がいないルームを作ってはいけないという条件があった場合、3つの集約に別れていると、一瞬管理者が居ないチャットルームが見えてしまう可能性があるわけです。
でも、一瞬だし、結果整合に倒れるんで構わないじゃんという話にもなります。
厳密にトランザクションでAtomic性を確保しようとすると、もの凄くアーキテクチャが複雑になって管理しづらい状況になるなるので、そこら辺をどうバランスとれば良いのかなって思います。
増田さん
要求と選択している設計技術にギャップが大きいから悩んでしまっているので、どっちかに倒したほうがいいと思いますね。
非同期を重視したい何らかの要求があるけど、結果整合性で問題があるっていうのなら、在庫が不足したら、不足したときに、不足を補うプロセスが動けばいいじゃない、見えてはいけない・存在してはいけないものが出てきたらそれを補うプロセスを動かせばいいじゃない。
そのようにに振り切ることで、非同期が使いやすくなると思いますよ。
逆にダメなんだと、リアルタイムで検知してアクションを起こさないと俺たちのビジネスの死活問題なんだという要求だったら、非同期ではなく同期性が強い実装をする選択になると思います。
要求と実装技術がねじれていると相当苦労すると思いますよ。
原田さん
Atomicなシステムが要るという話ですが、会社の勘定系って結果整合性システムですからね。判ってますか?
Atomicが本当に必要という担当者が居るのなら、今日の夕方6時の決算表見せてくださいと言えば良いのです。
大体決算表がでるのに一ヵ月ぐらいかかります。それぐらいの結果整合ということです。
参加者
この話は、設計上どこに落とし込むかでは無く、UX設計のプロセスが複雑になるという話だと思うのですよ。
特にUX設計しているプロデューサーなりビジネスオーナーと、設計している人が同一人物ではないときに、『ここまで画面設計したからさあ作れ』と言われて、そこで初めてエンジニアに回ってきたりすると、これは結果整合性にしないと現実的ではないから差し戻しする時に、前の人が偉い人だったりしたり、ビジュアルなところを大事にしていたりすると、また1週間近く画面設計やり直ししないとねという話になりかねないと。
そういう意味ではUX設計は複雑になると思うのですよ。そういう処の悩みなら私もよく抱えます。
わりと社内政治とかも絡んできます。
追加質問になりますが、そういう処の調整の仕方に関する知見ありますか?
エンジニアが優秀でハナッからそういうところに、鼻をつっこんでいって実現性があるか先に考えておくと言えればいいのですが、どうやってそういう場に持っていくのか、あるいはそこで確保出来なかった時に、どう収集つけるのか、宜しければ教えてください。
登壇者全員
・・・・(無言)
原田さん
みんな鼻が良いから、真っ先に逃げたみたいだよw
高江洲さん
はい、お時間なので続きは後ほど、一旦休憩はいりまーす。
その後
会場提供して頂きました「フューチャーアーキテクト株式会社」様の会社紹介、LTと続き、お酒の提供も手伝って、場は和やかな雰囲気に・・・。
しかし、かとじゅんさんの『お前ら、もっと近くに来い!!(意訳:マサカリが届かない)』の一言で、一気にヒットーアップ。参加者が皆前に押しかけ、各々にディスカッションが始まりした。
ここからは、ノートPC打つ暇もなく覚えている限りの項目です。
- かとじゅんさんをDDDに染めた都元ダイスケさんのなれそめ話
- DDD本は読むたびに理解が深まる螺旋階段
- 原田さんはカルチャーブレイカー
- Eric evansの近況について。近年はデスマプロジェクトに捕まっていた?
- AkkaのJonas Bonerの話
- マルチパラダイムデザインとDDDが示すドメインの違いについて
- Jim CoplienがDDDeurope2016に突撃した話
- 別々の道パターンの新解釈について
- "java以外"でのDDD実践について
- 純粋関数型をJimCoplienもディスってた話
- スコープリークについて
- ActionSpript3の素晴らしさについて
- メソッド切り出しはゴールではなく、オブジェクト化への第一歩
- みんなコンテキストを共有しないと判らないって言い訳し過ぎ
- DDDとscrumについて
- Jeff Sutherlandの最近の不満について
- DDDとXPについて
- エンジニアから起こる業務改善
そして勢いそのままに、近くの居酒屋に突入して行ったのでした・・・。