増田亨さん ドメイン駆動設計の正しい歩き方 を聞いてきました #bpstudy
BPStudy#141〜DDD(Domain Driven Design)実践の現場 - connpass に行ってきました!
特に心に残ったことまとめ
以降、ノート
言葉の使い分け:ビジネスロジック vs ドメインロジック
- 「ビジネスロジック」は、そもそものビジネスのルール。ソフトウェアかどうかは関係ない。(ITを使っていないビジネスはいくらでもある)
それに対して
コアドメインに集中する
コアを切り出して集中することで、不思議と周りも綺麗になっていく。
例えばホテルの予約サイトなら…
独立させたら、特徴を掴むためにモデリングする。自然言語も使って良い。
この段階でのモデルはあくまで「仮説」。仮説を確かめるために、コードを書いてみる。
すると…
コーディングしづらいなどの問題が見つかることがある。
その場合、「モデルにフィードバックする」。
コーディングしづらいのは、モデルが適切でないのかも。モデルを更新し、再度、コーディングを試してみる。
…というように、モデルとコードを行ったり来たりすることが重要!!
そして、このモデルは実装のために作っているので、必ずしもきれいにならないことも多い。*3
何が中核なのか。
「幼児の寝具」ではないだろう。
シーズンか、一室何名か、特別室/一般室か。
どれがコアなのかわからなかったら、3つそれぞれを軸にしたコードを書いてみる。
数時間書けばわかるはず!!*4
ビジネスを継続的に学ぶ
よくある失敗の一つが、「ビジネスを表面的に捉えて理解した気になる」。
もし深く理解できていれば、例えばサンプルの計算結果のタイポに気づけるはず。
あるいは、書かれていない部分の計算結果がわかるはず。
更に、周辺のビジネスの理解は重要。
どんな背景があるのか。
周りが分かってくると、コア部分で何を作らなければならないかがまた見えてくる。*5
他の方のレポート
- BPStudy#141〜DDD(Domain Driven Design)実践の現場に行ってきた #bpstudy - kntmr-blog
- BPStudy #141 DDD実践の現場レポート - Koka18’s diary
- BPStudy#141〜DDD(Domain Driven Design)実践の現場に参加してきた(DDD初研修) | Somurie Engineer
- DDD実践の現場の増田さんの話をまとめてみた - TAMALOG
- BPStudy#141〜DDD(Domain Driven Design)実践の現場に行ってきました - yachiy note
- BPStudy#141〜DDD(Domain Driven Design)実践の現場 まとめ - Togetter
*1:まさに「ホテルの予約サイト」の「料金計算」を主の生業として数年やってきた人間なので、このお題の登場にはビックリ
*2:検索や予約はコアではない… は私が言ったんじゃなくて増田さんの言葉ですからね!
*3:実装のためでない、ビジネスの理解のためのモデルにも価値がある。ただし実装には貢献できないかもしれない。これらは切り分けて考える
*4:これが今回一番心に刺さったフレーズなのです
*5:これ、よく私言ってるのですが… エンジニアはビジネスの背景をきちんと理解し無くてはならない。今の私達の現場は人数が増えてきたので、ポジションが別れている。高度なサッカーで11人がボールに群がっていくことはないはず。一方で、11人それぞれが、自分のポジションのことだけでなく、他の10人がどんな意図でどんな動きをしているのか理解できなければ、チームプレーはできないはず!
*6:・冒頭、「突然わけのわからないストーリーが始まる」ので、はじめは読み飛ばすべし ・結構な前提知識が必要 ・文章の構造を捉えつつ、重要なところだけ読む ・文章に癖があって読み方のコツが必要 という説明を聞いて、「それ普段、お仕事で読んでいる某文章と全く特徴が同じなんですけど…」 と思った次第。大事なことが書いてあるけど読みにくい文章の読み方って共通点があるのかな。
VOYAGEさんの「技術力評価会」がすぐにでも取り入れたいくらい面白かった! #EM集会
今日はこちらに参加しました!
エンジニアのマネージメントで悩んでいる人が集まる会 #3 - connpass
今までそれなりにいろんな勉強会/ミートアップに参加してきたのですが、
「マネジメント」「マネージャー」を冠した会は初めてでした。
主催者の方や、一部の参加者の方はアジャイル系と重なっている印象でした。
なんと、寿司と酒が出てきましたよ。
後半の懇親会用のものだったようですが、発表が始まる前からカンパーイ!
VOYAGE さんのめっちゃ攻めてる「技術力評価会」
今回のテーマは「評価」。
一件目の発表、@katzchangさんの「技術力評価会の話」の発表が大変印象に残ったので、こちらを書き留めておきたいと思います。
VOYAGE さんでは、評価制度の一環として、「技術力評価会」という制度が行われているそうです。
こちらの資料が詳しいのですが、
要点をまとめると、
・半年に一回行われる
・一回90分のセッション
・被評価者は、自身の成果を発表する
・評価者は発表を聞き、被評価者と議論する
・セッション終了後、評価者は評価レポートをまとめ、口頭で被評価者にフィードバックする
・被評価者の発表内容と、評価者の評価レポートはすべて社内に公開される
・評価者は、原則、被評価者と別のチームから選ばれた、「ミドルエンジニア」「シニアエンジニア」「シニアより上のグレードのエンジニア」
・社外評価者(他社のCTOだったり、デブサミで発表しているような人だったり…)が参加することもある
・評価者と被評価者のマッチングは、評価委員会(各チームのリーダーで構成)が決める
・後日(評価レポートが出揃ったあと)、被評価者はチーム内で、技術評価会の振り返りを行う。
・振り返りでは、評価会で得たFBの共有(例えば、「そこはmysqlを使ったほうがいいんじゃ?」のような意見)がチームに共有される
・また、評価会制度そのものが振り返りの議題に上がることもある
というものでした。
この評価会制度、とても良さそうだなと思ったのが二点あります。
1. 被評価者が、コンテキストが違う人に対して説明するスキルを磨ける
個人的には、発表スキルは、エンジニアにとって、とても大事なスキルだと思います。
しかも、別のチームの人(=被評価者のやっていることをよく知らない人)に対して説明するということで、一段更に上のプレゼン力が求められるわけです。
プレゼンに限らず「ちょっと説明が下手な人」って、聞き手が何を知っていて何を知らないのかが分かっていないケースがままあるので…。
発表してくださったkatzchangさんは、自分のメンバーに対して、「転職するとき、採用面接で、コンテキストが違う人に自分がやってきたことを説明する力必要だよ」と言ってモチベートしているそうです。
2. 評価者が、「他社を評価する」という経験を得られる
ミドルクラスのエンジニアって、普通にしているとあまり「他社を評価する」機会がないんですよね。
(360度評価をしていなければ)人の給料を決める機会がないですし、
採用面接の面接官をしているケースも少ないんじゃないかと。
そういったメンバーに、「他人を評価する」機会を与えられるということ、とても素晴らしいと思います。
なぜなら、「評価する」ことを考え、知ることによって、「自分が評価されるとはなにか」を考えることができるようになるからです。
以上の二点(だけではないですが)から、「技術力評価会」、とても興味深い制度であると感じました。
一方で、給料が関わってくるからこそ、何かしら批判的な意見も出てくるようで*1、
katzchangさんのように高い目線を持ったシニアな方が、意味を伝え、啓蒙し続けて行くことが、仕組みを維持するための鍵の一つのようです。
いきなりこれを評価制度に取り込む、というのは難しそうですが、
「コンテキストが違う人に自分の成果を伝える」「他社を評価する」
という仕組みを上手く自身のチームに取り入れたいと感じました。
*)とはいえ、評価だからこそみんな真剣にやるわけで、お金がかかってないとモチベーションがわかない人はいそう…。
懇親会で話したこと 走り書き
評価が難しいタイプ
- アベレージヒッター
- 三振かホームランかタイプ
※アベレージヒッターは挑戦がないところが辛い
※インフラのプラットフォームを提供している会社で、明確に「三振タイプは評価しない」を打ち出した会社がある
挑戦は認めてあげたいけど…
- それでやらかしていいのはジュニアレベルくらいまでなのでは。ある程度のレベルの人が、「リスクも考えずにやってみました」は「挑戦」ではない。
ドバーッと人を採用した
- 「様々な」人が増え、価値観もバラバラに
覚えた単語
- ノーレイティング
- OKR
*1:プレゼン力があるやつの勝ちじゃんとか、評価者ガチャじゃんとか
増田亨さん「マイクロサービス 4つの分割アプローチ」を聞きに行けなかったんだけど教えてもらったのでまとめてみる #jjug_ccc
背景
私の増田さん追っかけは2017年11月に遡るのですが、
https://taichiw.hatenablog.com/entry/2017/11/05/175105
当時、APIの設計や、そこからつながるマイクロサービスの設計については、まだ試行錯誤されている段階… というお話を聞いていました。
ありがとうございます。APIのところは、私も、まだ悩みながらやっています。APIの利用者が特定できる少数の場合と、不特定の多数を想定する場合では、違う設計になりそうですね。
— 増田 亨. (@masuda220) 2017年11月5日
当時の私も絶賛、「どう切るのが良い切り方なのだろう」と悩んでいたところだったのですが…
あれから一年半あまり経って、今年のJJUG CCCで増田さんがマイクロサービスについて話される ということで、これはぜひ聞きたい! と思っていたのです。
マイクロサービス:4つの分割アプローチの比較
思っていたのですが、都合が合わず、参加できず………
ということで、せめて公開された資料でも後で読もうと思って備忘録代わりにFacebookに投げておいたところ…
「聞きに行きましたよ!」と優しい同僚が話しかけてくれたのです。
こういうのはダメ元でSNSに上げてみるもんだなぁ!
と、いうことで、聞いた話と公開されている資料などなどから勝手に感じ取った感想を書き残しておきたいと思います。*1
分割には4つのアプローチがある
タイトルにもある通り、サービスの切り方には以下の4通りのアプローチがあり、これが組み合わせて使われているのが現状 というお話だったようです。
…ということで、一年半前の私の疑問、
「計算ロジックはデータと同じサービス内に置くべきか否か」は
ケース・バイ・ケース ということになってしまうようです。
ただ、今回、4パターンに名前をつけてもらったことで、名前を使った議論ができそうな予感です。これについて少し見ていきたいと思います。
…………と思ったんですが、直接聞かないとやっぱりよくわかんないなこれ。
モノリスを分解していく過程で、
ざっくり縦(時系列)に切る → ビジネスファンクション
↓
「そこから」更に縦に切る → 動詞/ユースケース
↓
「そこから」横に切る → 名詞/リソース
…というようにも読めたんだけど、そんな絵がどこにもないということはそういう意味じゃないのかな。
そしてこの、「ビジネスルール中心の構造」って
これまたそういう流れの設計は語られてないから違うのかなぁ…。
んー 結論 やっぱり資料だけじゃよくわからないから直接聞きたかった!
とりあえず明日、もう一回同僚の彼に聞いてみよう。
参考にさせていただいた資料
*1:ということで、本ブログは、直接発表を聞いた者の感想ではございません
ISO25000を読んでみる - ISO25010 The quality model 前半
「『品質がいい』ってなんだよ!?」を定義したISO25000 の中に含まれる、ISO25010を読んでいます。
こちらのポータルサイトを中心に読み進めているのですが、
iso25000.com
抽象的な説明が中心(&英語)で理解しづらいところがあるため、「こういう意味かな? 例でいうとこういうことかな?」と考えたことをメモとして残します。
The quality model
「ソフトウェアの品質」を8つの項目に分類し、更に各項目が複数のsubcharacteristicsを持つ構成になっています。
上記図はhttps://iso25000.com/index.php/en/iso-25000-standards/iso-25010より。
Functional Suitability
所謂「機能要件」。品質とかテストとか言うとこれが注目されがちですが、"Software Product Quality"として定義されている8項目の中の1つに過ぎません。
Functional Suitabilityを構成する3つのsubcharacteristicsのうち、
Functional completenessは、機能が網羅されたチェックリストにどのくらい『実装されていますチェック』を付けられるか
Functional correctnessは、そのリストになっている各機能がどれくらい正しい結果を返しているのか
と解釈しました。
Functional appropriatenessは、
Degree to which the functions facilitate the accomplishment of specified tasks and objectives.
とあったのですが、この定義がよく理解できませんでした。
こちらのCase Studyを見ると、
http://www.aqclab.es/images/AQCLab/Noticias/SQP/software-quality-management-evaluation-of-software-product-functional-suitability-a-case-study.pdf
understood as the ability of the system to carry out the requirements that are needed for the different usage objects that have been specified.
とありました。ということは、先程の「チェックリストで定義された機能一覧」が、そもそもどの程度ユーザの要求を満たしているか、
要件定義そのものの品質チェック… ということでしょうか?
ISO25000を元にした、JISでは、
明示された作業及び目的の達成を,機能が促進する度合い。
と訳され、
例 不要な段階を除いて,作業を完成するために必要な段階だけを利用者に提示する。
という例がついていました。*1
Performance efficiency
「パフォーマンス」と言ってもいろいろあるようでして。
Time behaviourは速度とスループットが要求を満たしている度合い
Resource utilizationはコンピュータのリソース消費に関する要求を満たしている度合い*2
で、最後のCapacityがまた分かりそうでわからない。
Degree to which the maximum limits of a product or system parameter meet requirements.
これだけ読むとナンノコッチャ って感じなのですが… またJISの怪しげな例*3に頼りますと
製品又はシステムのパラメータの最大限度が要求事項を満足させる度合い。
注記 変数には,保存することができる項目の数,同時に利用する利用者の数,通信帯域,トランザクションのスループット,及びデータベースの大きさを含む。
ということで、要は「いろんな値の最大値」がちゃんと満たされているかどうか ということのようです。
Compatibility
Co-existence
Degree to which a product can perform its required functions efficiently while sharing a common environment and resources with other products, without detrimental impact on any other product.
サーバの相乗りとか、あるいは一台のPCやスマートフォン上で複数のアプリが動く際に、他のソフトウェアに悪影響を与え(自分ばかりCPUやメモリを食うとか)ずに動作できる度合い…ということでしょうか。
Interoperability
Degree to which two or more systems, products or components can exchange information and use the information that has been exchanged.
と、定義されています。
ここまではすべて単体のシステムに対する指標だったのですが、"Degree to which two or more systems, products or components" なので、評価の対象が複数システムの指標のようです。複数システム間でどれだけ情報の共有がなされているのかを表す指標です。
同じ区役所のビルの1階と3階と5階に、同じような内容をそれぞれ別のフォーマットで書いて提出しなくてはならない*4お役所のシステムはInteroperabilityが最悪なわけですね。何のためのマイナンバーですか。
Usability
なんとなく使ってしまう言葉ですね。
Degree to which a product or system can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use.
と、定義されていて、specifiedが何度も出てきます。
「『特定の』ユーザが、『特定の』状況において、『特定の』目的を達成する ことに対してどれだけ役に立つか」を表す指標なんですね。
逆に言えば、そもそもユーザとして想定されていない層の人達が「使いにくい!」と感じることは、この指標の観点に於いては問題ない ということになります。
subcharacteristicsは6つです。
Appropriateness recognizability : なにか達成したいことがあるユーザに、このプロダクト(システム)が使える! とそもそも認識してもらえる度合い。
Learnability : いざ使う気になってくれたユーザの、操作方法の学びやすさ。
Operability : 操作性。んー どういうのを指してるのかな…
「スマートフォンのUIなのにやたらボタンが小さい上に並んでいて誤操作しやすい(PCでマウスだったら特に押すのが難しくない)」のは、Operatabilityが悪い例でしょうか。
User error protection : ユーザが誤った操作をしずらい度合い。
「数値しか受け付けないフォームは数字しか入力できないようにする」はここに入るでしょうか。
User interface aesthetics : "aesthetics"は「美学」という意味だそうです。狭義の「UIが良い/悪い」はここに入りそうです。
Accessibility :
Degree to which a product or system can be used by people with the widest range of characteristics and capabilities to achieve a specified goal in a specified context of use.
ということで、ここでは"people with the widest range of characteristics and capabilities"の広さが指標になっています。
Usabilityのはじめに、特定のユーザが、特定の状況で、特定の目的 と書きました。この『特定のユーザ』の範囲が広く、多くの人から使ってもらえる製品 = Accessibilityが高い製品 と言えるようです。
リアルタイムにそこそこ重い処理を実行するためには、前処理が重要… なのかな? #jsug
JSUG勉強会 2019その3 LINEにおけるSpringの活用 に参加してきました。
ここがとっても気になったのです。
Personalized content recommender systemであるSmart Channelは、ユーザーの属性や趣味趣向を推定し、各個人に最適なコンテンツを推薦するServiceです。
LINEの膨大なトラフィックを受けながら、可能な限りリアルタイムにRecommendをするために、Architectureや実装にいくつかの工夫をしています。
「個人個人に違う結果を出すために、毎回リアルタイムで計算」ってどこかで(私が)(業務上)聞いたことある!
すごい気になる!
ということで行ってまいりました。初LINEさんオフィスです。
会場のカフェ。おしゃれだった。
さて、@hackmylife さんの Personalized content recommender system on Springです。
自分が気になっていた、以下にリアルタイムに処理をするか、という点。
以下の二点が特にミソなのではないか と感じました。
・Redisとの通信がWebflax形式のNon-Blocking. フィルタリングなどの処理はSubscribeしたときに動く。
・前もってTrainer側で、Rankerが「扱いやすいように」処理する。例えば、逆行列を求める処理がアルゴリズム上必要なのだが、これは事前に処理しておく。
この「事前処理」はスライドのこちらのページで触れられています。
"User traffic" を起点に動作する、CRS Engineが見に行く"CRS Model Redis Parameter"。
こちらに格納されているデータが、「CRS Engineが扱いやすいように処理された」ものなんだそうです。
IntelliJ IDEAのSequenceDiagramプラグインが便利
この、SequenceDiagramプラグインで、
vanco.github.io
こんな感じのシーケンス図が描けます。
素敵なのが、
- 好きなメソッドから始められる
- 深さが選べる
点です。
コードレビュー時などに、深さ2でServiceクラスから始めると、私の好きな感じのコードになっているかどうかがよくわかります。
参考:持論:Application Layerがシンプルなコードは読みやすい - エンジニア的なネタを毎週書くブログ
以前は、こういったコードから自動生成された図は、ノイズが多くて使い物にならない…と思っていました。
けれども最近は、
「自動生成された図が汚い、ということはそもそもコードが悪いのでは?」
と思うようになってきました。
例えばこれ。
右から左に呼び出しが伸びてるのが気持ち悪いです。
以前の私であれば、「この呼ばれているクラスを右に持っていければいいのに… ツールがイケていない!」と思っていたところでしたが、
そもそもこんな向きに呼び出しがかかる、元のコードが悪いのではないでしょうか。
こういう考え方になってきたのは、12月のJJUG CCでirofさんの「JIGを使った設計」を聞いたからなのかなぁ… と思います。
【極論ですけど】JavaでforEachを使ったら負けだと思う
正直使い所がわからないんですよね、forEach.
ログとかprintfとかする以外は…
コレクションを更新するな
未だに時々見るのがこういうコード。
List<X> list = new ArrayList<>(); 適当なコレクション.forEach() .map(t -> list.add(t.getXXXX()));
これとっても良くない。
スレッドセーフでない
上記をあまり深く考えずにパラレルストリームにしちゃいますと
List<X> list = new ArrayList<>(); 適当なコレクション.forEach().parallelStream() .map(x -> list.add(x.getXXXX()));
ArrayListに対する追加処理がスレッドセーフでないため、確率的に不具合が起きてしまいます。*1
パラレルにしなければいい…のですが、Project Lambdaの目的の一つがマルチコアへの対応なわけで、「parallelStreamを使って並列化できないものはラムダ式で書くな」くらいに私は思っています。(私の勝手ルールではありますが)
Lambdaで更新するの「関数」でない
Lambda式内では外で定義した変数に代入ができません。
これは、「状態」を極力排除することによって、バグの入り込む余地を減らすため… と私は認識しています。
ですが、上記のようにコレクションに対する操作や、Setterでの代入はJavaの言語仕様上できてしまいます。
…とはいえ、できるからやっていい、というものでもないと思います。
「リストを作る」と明確に書く方法がある
List<X> list = 適当なコレクション.stream() //parallelも可
.map(X::getXXXX)
.collect(Collector.toList());
そもそもこのように、リストを作るための書き方が用意されているのに、これを使わずに汎用的なforEachでなんとかする… というのは美しさに欠けます。
更新しないとなると、forEachは出力くらいしか使いみちがないのでは
上で書いたとおり、コンパイルエラーにはならない… とはいえ、Lambda式内で何かを「更新」するのは不適切と考えます。
そうなると、冒頭に書いたとおり、何かの出力くらいしか使いみちがないなぁ… ということになり、
よっぽどのことがない限り、「forEachを使ったら負け」だと思うのです。
*1:私が経験したことのある事象だと、「適当なコレクション」よりも多い要素がlistに追加されるという謎現象が発生し、その要素をgetするとnullが入ってる → ヌルポで落ちる というものを何度かみました。