JJUG CCC 2019 Fallに行ってきました
11/23に行われたJJUG CCC 2019 Fallに参加しました。
聴講したセッションについて忘れない内に吐き出しておこうと思います。
Gradleを完全に理解した人が、何も分からなくなるための第一歩
@opengl-8080 さん
https://qiita.com/opengl-8080/items/c482998fa15ce738e2ba
Gradleについてタスクの作り方や複数の方法で実現できる関心事があったときにどのようなところに注目して選択するべきかなどのお話が聞けて、 普段SpringBootなアプリケーションを開発するときに何となくでGradleを触っていて深堀りしたことがなかったので、仕組みの話やご本人が初心者のときに迷ったポイントなどが聞けて勉強になりました。
ちょっと込み入ったことしようと思ったときはぜひ今回の発表と資料を参照しながら試してみようというモチベーションを頂きました。
Javaで学ぶオブジェクト指向プログラミングの基礎知識
増田亨(@masuda220)さん
www.slideshare.net
現場で役立つシステム設計の原則であえてカタカナ英語を使わないように記述した内容について、オブジェクト指向の用語を使ってわかりやすく説明されていました。
新人研修でわかったようなわからないような、とりあえずパターンだけを何となく覚えがちなオブジェクト指向について、しっかりこういうことだと腹に落とし込めるよう構成されていて、ぜひぜひ変な癖が付く前に新人の人とかにもおすすめしたい内容でした。
型は値の範囲と操作を制限するということについて初心者でもわかりやすいようにカプセル化と交えて説明されていて、内容を教わる側としても、知識を布教する側としてもどちらに視点でも参考になりました。 DDDという言葉は一言も登場してないのに繋がりも感じ、DDDの用語に対してアレルギー反応を示しそうな層にも優しい話の流れや例を紹介されていて勉強になりました。
開け!ドメイン駆動設計の扉
成瀬 允宣(@nrslib)さん
資料は諸般の事情により資料のWeb公開はしないみたいです
JJUG CCC #ccc_e3 のトークスライドは諸般の事情により Web 公開しないことになっております
— nrs (@nrslib) 2019年11月23日
すみませぬ
togetterでまとめてくださているのでそちらを読むだけでも雰囲気つかめるかもしれないです。
今日の想い出にセッション「開け!ドメイン駆動設計」の様子を togetter でまとめました。
— nrs (@nrslib) November 23, 2019
「平子っぽい」発言はおそらく、たぶん、もしかしたら自分のセッションに対するツイートな気がするので追加しました…。
ご査収ください。https://t.co/MMlj1E9tko#jjug_ccc #ccc_e3
Evans本の問題領域の理解やユビキタス言語の発見、知識の蒸留から実装パターンまでの話をわかりやすい具体例を交えて説明されていました。
この例が非常にわかりやすくパクりたいレベルで、内容のわかりやすさももちろんすごいのですが、教える人としての力量も見せつけられました。 特に知識の蒸留のところの鉄鋼製造ドメインにおける炉の温度管理の話が実例として刺さる内容でした。
実装パターンとしての集約の話や値オブジェクトの話などもこういう風にするとこう嬉しいと、形ばかりがフォーカスされがちなところも心意気から説明されていて非常にわかりやすかったです。
増田さんのセッション→成瀬さんのセッションの内容で送る新人研修があったら初心者でも一気にステップ駆け上がれるなという印象を受けました。
長く続くサービスがモダンであり続けるには
角田拓己(@chan_kakuz)さん slides.com
改善活動の話で、息が長くなってきたサービスをどういい感じに維持していくかという視点で現在取り組まれている内容の紹介でした。 わかりみを感じつつ、gradle-versions-pluginなど知らなかった便利ツールを教えていただいたりと現場のお話を聞けて参考になりました。
一番ビックリしたのが、登壇者の方が新卒2年目の方で、2年目でこの内容もそうですし話し方も落ち着いててレベルが高く度肝を抜かれました。
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション - 開発ツールやプロジェクト構成も含めて45分で丸わかり
株式会社カサレアル(@PR_CASAREAL)さん
www.slideshare.netスポンサーセッションだからか宣伝色強めでしたがSpringBootなRest APIの作り方や3層アーキテクチャ、Angularの話などSPA + WebAPIという今ありがちなアプリケーションの作り方について基本から説明されていました。
誤解されがちな内容についてもきちんと否定されていたり、出来ること出来ないことを明確に説明されている印象でした。
JVM入門 -Javaプログラムが動く仕組み-
Abe Asami (きの子)(@aa7th)さん speakerdeck.com
JVMについて基礎的な仕組みからGCのタイミングまで裏で何が起こっているかを理解できるようになるための内容でした。 新人研修以来ご無沙汰になっていたGCの仕組みなどを復習しつつも更に深いところまで解説があり勉強になりました。
スタックトレースが何故そういう名前なのかというのが解説の中で理解出来、普段表面しか捉えずに利用している仕組みの裏側が知れてよかったです。
挿絵のイラストも可愛いかったです
DIコンテナ入門
うらがみ(@backpaper0)さん backpaper0.github.io
SpringなどでおなじみにDIコンテナについてどういうものなのかというのと、登録したComponentの利用の仕方など普段の業務で利用している技術について今日から使える内容が多く勉強になりました。
SpringでのAOPの実現の仕組みや注入についてもわかり易い言葉で説明されており、私も普段コンストラクタインジェクション推しで開発をおこなているので、共感できる内容も多く簡潔にまとまっているので他の人への伝える際の参考にもなりました。
終わりに
Springに引き続きFallもJJUG CCCに参加しました。
私も開発者としてやらせていただいていて、自分の知識を仕入れるという一方で、他の人に伝えるという機会も増えてきたのでそういった視点でも登壇者の皆様から多くのインプットを頂けて非常に勉強になりました。
知ったつもりになっているものを学びほぐすという意味でも収穫は多く、理解に厚みが増しました。
増田さんのセッションからの成瀬さんのセッションはオブジェクト指向からドメイン駆動設計に繋げる良い足がかりになると思い、私も伝播の際にもお二方の話した内容を意識しつつ本質を捉えた開発ができるよう伝えられればなと強く感じました。
貴重な学習の機会を提供してくださった、JJUG CCC 2019 Fallの実現に携わった方々、登壇者の方々、ありがとうございました。
AWS認定ソリューションアーキテクト-アソシエイトの試験勉強メモ
先日AWS認定ソリューションアーキテクト-アソシエイトを受験して合格したので、勉強の際に間違った部分のメモを忘れない内にダンプしておこうと思います。
以下メモ
グローバルインフラストラクチャとネットワーク
VPC
ルートテーブル
サブネット毎に1つ設定 1つのルートテーブルを複数のVPCで共有は可。1つのサブネットに複数のルートテーブルの適用は不可。 宛先アドレスとターゲットなるゲートウェイ(ネクストホップ)を指定する。 VPCにはメインルートテーブルが有りサブネット作成時に指定しない場合のデフォルトのルートテーブルになる。
セキュリティグループとネットワークACL
セキュリティグループ
インスタンス単位の通信に利用
ステートフル (デフォルト拒否)
ネットワークACL
サブネット単位の通信に利用
ステートレス(デフォルト許可)
ゲートウェイ
インターネットゲートウェイ
各VPCに1つだけアタッチすることができる。
VPC内のリソースからインターネットへアクセスするためのゲートウェイ。インターネットゲートウェイをVPCにアタッチするとVPCからインターネットに出ることができる。
NATゲートウェイ
プライベートサブネットからインターネットへ接続するために用いる。AWSではマネージドなサービスとして提供されていてAZ内で冗長化されている。
NATゲートウェイを利用しない場合はNATインスタンスと呼ばれるEC2インスタンスを利用してインターネットにアクセスする。この場合は「送信元/送信先チェック」を無効化し、自身へのトラフィックを破棄する設定が必要になる。EC2インスタンスを利用するため単一障害点にならないよう冗長化の仕組みを検討する必要がある。
インターネットゲートウェイとNATゲートウェイ
パブリックサブネットにあるものはインターネットゲートウェイを通じてインターネットに出られる。
プライベートサブネットにあるものはインターネットゲートウェイへ直接接続できないので同じAZのパブリックサブネット内に配置したNATゲートウェイを通じてインターネットへ出る(前段に噛ますイメージ)。
仮想プライベートゲートウェイ
VPCがVPNやDirect Connectと接続するためのゲートウェイ
VPCエンドポイント
VPC内からインターネット上のAWSサービスに接続するための方法。
ネットワークレイヤーのゲートウェイ型とアプリケーションレイヤーのインタフェース型の2種類存在。
ゲートウェイ型
ルーティングを利用。ルートテーブルに指定されたターゲットを追加することでS3やDynamoDBへインターネットを経由せずに接続できる。
インターフェース型
AWS PrivateLinkとも呼ばれ、AWSへのAPIコールに対してインターネットを接続せずに実現できる。
VPCピアリング
異なるVPC間をプライベート接続する機能。インターネットを経由しないでAWSのプライベートネットワーク内で直接通信できるようになる。異なるAWSアカウント間でも可能だがネットワークアドレスが一致or重複している場合は接続できない。
VPCフローログ
VPC内の通信の解析に利用。送信元/送信元アドレス、プロトコル番号、データ量と許可/拒否の区別が記録される。
ネットワーキングとコンテンツ配信
Route53
権威DNS
権威DNSはドメイン名とIPアドレスの変換情報を保持しているDNS ↔ キャッシュDNSは変換情報を保持していないDNS
ホストゾーンとレコード情報
ホストゾーン:レコード情報の管理単位。通常はドメイン名。
Zone Apex:最上位ドメインのこと
レコード情報:「www.example.comはIPアドレスが192.168.0.100である」のような変換情報。
レコードタイプ
Route53では各レコードに対してTTLを設定することができる Aレコード:ドメイン名からIPアドレスを取得 MXレコード:対象ドメイン宛のメール配送先ホスト名を定義 CNAMEレコード:ドメイン名から別のドメイン名を参照。ホストに関係なく登録できる。 ALIASレコード:各AWSプロダクト(ELB, CloudFront等)で利用するDNS名専用の、CNAMEレコード風の挙動を実現するレコード。ZoneApexの別名解決に用いる。
トラフィックルーティング
シンプルルーティング:設定されたレコードの情報に従ってルーティングする
フェイルオーバールーティング:ルーティング対象となるリソースへのヘルスチェックを行い、利用できるリソースへルーティングする
位置情報ルーティング:接続クライントの場所に基づいて地理的に近い場所へルーティングする
地理的近接性ルーティング:リソースの場所に基づいてルーティングする。リソースの移動の際に使用する。
レイテンシーベースルーティング:最もレイテンシーが低いリソースへルーティングする
複数値回答ルーティング:1つのレコードに異なるIPアドレスを複数登録しランダムに返却されたIPアドレスに接続。ヘルスチェックがNGになったIPアドレスは返却されないので正常に稼働しているサーバに対してのみアクセスを分散できる。
加重ルーティング:複数のリソースに対して加重度を設定し指定した比率に応じて処理を分散するようルーティングする
DNSフェイルオーバー
Route53が持つフォールトトレラントアーキテクチャ
フォールトトレラントアーキテクチャとはシステムに異常が発生した場合でも被害を最小限度に抑えるための仕組み。
コンピューティングサービス
EC2
EC2における性能の考え方
インスタンスタイプ
mとかpはインスタンスファミリー、数字は世代を表す。xlargeなどはインスタンスサイズを表す。
Dedicatedインスタンスはホストマシンを専有するタイプのインスタンス。
インスタンスメタデータ
インスタンスID
プライベートIPv4アドレス
パブリックIPv4アドレス
ローカルホスト名
公開鍵
AMI
EBS-Backedインスタンス or Instance Store-Backedインスタンスの2種類。EBS-Backedはデータを永続化でき、Instance Store-Backedは揮発性のためインスタンス停止時にデータが消える。
ELB
クロスゾーン負荷分散を有効にすると複数のAZに登録された全てのEC2インスタンスに対してリクエストを均等に分散する。
ELBの種類
Classic Load Balancer:L4/L7レイヤーで負荷分散を行う。
Application Load Balancer:L7レイヤーで負荷分散を行う。CLBよりも後に登場し機能も豊富。
Network Load Balancer:L4レイヤーで負荷分散を行う。HTTP(S)以外のプロトコル通信の負荷分散をしたいときに用いる。
Auto Scaling
EC2だけではなくELB, RDSに対しても設定できる。
最大インスタンス数などのスケールためのルールはAutoScalingGroupに記述する。
運用支援サービス
CloudWatch
メトリクス
標準メトリクスにある
CPUUtilization: CPU使用率
DiskReadOps: (指定期間における)インスタンスボリュームストアからの読み取り回数
DiskReadBytes: インスタンスボリュームから読み取られたバイト数
NetworkIn: すべてのネットワークインターフェースから受信されたバイト数
カスタムメトリクスで設定する必要がある
メモリ使用率
ディスク使用量等
等など
CloudWatch Logs
EC2などにCloudWatch Logs専用のエージェントをインストールする必要がある。
CloudTrailやVPCフローログ等様々なAWSのログを統合的に収集する。
CloudWatch Events
AWS上のリソースを監視しあるイベントをトリガーにアクションを実行する機能。例えばEC2インスタンスの状態を監視し変化があればLambdaやSNSを実行するなどができる。CloudWatchはメトリクスを監視していて、CloudWatch Eventsは状態を監視している。
スケジュールもイベントとして取り扱える。
GuardDutyと連携するときはGuardDutyの状態の変更をCloudWatch Eventsで監視する
CloudWatchアラーム
CloudWatchで監視している項目がある一定値になった場合にアラームとアクションを起動できる。
ストレージサービス
EBS
スナップショットを作成を開始する際は止めておく(デタッチしておく)。スナップショットを取り始めたらアタッチをしてもOK(完了を待たなくても良い)
AZをまたぐことは出来ない。
ボリュームタイプ
汎用SSD:デフォルトのSSD。安価。OSのルート領域などI/Oを要求されないデータ領域で利用
プロビジョンドIOPS SSD: 高パフォーマンスを実現。ミッションクリティカルなシーンで利用される。汎用SSDより高いパフォーマンスがほしい場合に利用
スループット最適化HDD:HDDタイプのストレージ。大容量を安価に利用したいとき。アクセス頻度が多いとき
Cold HDD:低コスト
EFS
スケーラブルな共有ストレージサービス。EC2やオンプレミスから利用できる。NFSの機能を有している。現状はLinuxのファイルシステムのみサポート
S3
ストレージクラス
スタンダード:頻繁にアクセスするデータの格納に適している。
標準低頻度アクセス:低頻度でアクセスされるものの、必要なときにアクセス可能なデータを格納するのに適している。
1ゾーン低頻度アクセス:RRS S3と呼ばれるもの。低頻度でアクセスされるものの、必要な時にアクセス可能なデータを格納するのに適している。1つのAZにしか格納されないため低コストだが、その分耐久性が低い。
オプション
デフォルトでリージョン内複製を有効になっている。バージョニングなどのオプションはユーザが任意で設定する。リージョン内複製をとっていても削除処理を行った場合は複製も消える(あくまで耐久性向上のための複製という見方?)。
バケットポリシー
削除の禁止を行うことで誤削除を防げる。
小技
ファイル名の先頭にランダムな文字列を付与するとインデックスが分散されてパフォーマンスの向上が期待できる。
Glacier
迅速(Expedited):1〜5分でアーカイブデータの取り出しが可能
標準(Standard):3〜5時間でアーカイブデータの取り出しが可能
大容量(Bulk):5〜12時間でアーカイブデータの取り出しが可能
データベースサービス
RDS
マルチAZ化可能。
リードレプリカにより読み取り性能の向上が可能(≠冗長化)
AutoScalingでリードレプリカを作ることも可能
SSL接続のためのオプションは--ssl-ca
Redshift
列指向データベース。
ペタバイト規模のデータを標準SQLで分析可能。
リーダーノードに対しコンピュータノードが1対Nで構成される。耐障害性を高めるにはノードを増やす。マルチAZは対応していない。
DynamoDB
DynamoDB Accelerator
DynamoDB用のインメモリキャッシュ
ElastiCache セッションを格納するのに良い。
セキュリティとアイデンティティ
KMS
AWS上で鍵管理を提供するマネージドサービス。
暗号化鍵の作成や有効/無効の管理、ローテーション、削除ができる
CloudHSM
AWSのデータセンター内に配置されるユーザ占有のハードウェアアプライアンス。
プロビジョニングサービス
Elastic Beanstalk
定番構成の自動構築
対応しているアプリケーション:Java, .NET, PHP, Node, js, Python, Ruby, Go, Docker
対応しているデプロイサーバ:Apache HTTP Server, Nginx, Passenger, Microsoft Internet Information Service(IIS) 等
AWS OpsWorks
OSより上のレイヤーの自動構築をサポート
ChefやPupperを利用できる。
AWSにおけるアーキテクチャ設計
AWS Well-Architectedフレームワーク
回復性の高いアーキテクチャを設計する
パフォーマンスに優れたアーキテクチャを定義する
セキュアなアプリケーション及びアーキテクチャを規定する
コスト最適化アーキテクチャを設計する
オペレーショナルエクセレンスを備えたアーキテクチャを定義する
AWS Trusted Advisor
コスト最適化
セキュリティ
耐障害性
パフォーマンス
サービスの制限
ストリーム処理
Kinesis Data Streams
ストリーミングデータをほぼリアルタイムで保存、EMRやLambdaなどの後続処理に流せる。
シャード単位でデータを分割して並行処理が可能。
Kinesis Data Firehose
ストリームデータをAWSの各サービスに配信、保存できる。
Kinesis Data Analytics
ストリーミングデータに対してSQLクエリを実行しリアルタイム分析を行う。
サービスの種類
グローバルサービス:S3, Route53
リージョンサービス:VPC
AZサービス:EC2, EBS, ELB, RDS
BPStudy#145〜進化する要件定義(RDRA meets DDD)に行ってきました(第2部)
DDDとRDRAを組み合わせて使うには
かとじゅん様(@j5ik2o)
感想
DDDを実践しようと思ったらRDRAの外側のレイヤーに注目する考え方が有用で、業務を理解しないことには適切なドメインモデルが導かれないというお話でした。
DDDとRDRAを組み合わせていく上で現場で実践していることをDDDとRDRAの用語の関係ベースで説明されていて、自分の中で対応関係が明確になりました。
DDDの文脈で重要視されている、コアドメインで仕事しているか否かという部分についても境界づけられたコンテキストとシステム価値を対応させることで判断の助けになるなど実務で使える知識を得ることができ勉強になりました。
かとじゅん様、ありがとうございましたm( )m
以下メモ
要求の分析したことを分析したまま実装に落とし込むというDDDの考え方(単一モデル)の元でRDRAを生かしたという観点での発表。
ドメインモデルとは
- 実装を見れば分析の結果がわかる、ビジネスルールがわかるという状態を目指す。
- 例えば、請求クラスは支払い期日に基づいているのでインスタンスを内包する可能性が高い。
いきなりドメインモデルを作れるか
- 初見だとほぼ無理であるためドメインモデルが導かれる元となる外部環境に注目する。
- システム価値を整理することでコアドメインで仕事しているか否かがわかる。
- システム外部環境を整理することでドメインモデルの輪郭が特定できる。その業務が未経験であればあるほど。
ユースケースモデル
- 今回の発表では文章だがRDRAだと図で表す。人間とシステムの対話のシナリオを示していて、(E)はEntity、(C)はコントロール(動詞の部分)、(B)はバウンダリーを表している。
- 用語の候補は操作マニュアル等が参考になる。
システム境界とBCEステレオタイプ
名詞
- バウンダリーはユーザーインターフェースのこと。
- Entityはドメインオブジェクトのこと。
動詞
イベントモデルから分析する
- イベントは他のシステムと連携することがある。
- 業務上で起きるイベントに注目してモデリングする(EventStorming)
ユースケースいきなりかけるか問題
- 業務知らないとユースケースは書けない
→ システム外部環境を知るべき
- 利用シーンを用いて、どのような場面で使われるかや利害関係者を紐づける。
→ 利用シーンや利害関係者がいない機能があったらそれはいらない機能。
→ ユビキタス言語の候補が整理していくと出てくる。
→ ユビキタス言語はこのような分析を行って初めてできるものであり、いきなり降って湧いてくるものではない。
概念モデル
声に出してモデリングのが良い。
→ 自分で言語化するときに違和感を覚えたものはモデリングがおかしい。相手に伝わる表現が大事。
→ どうしても声に出すだけでは伝えるのが難しいものはホワイトボードにインスタントに絵を描いて説明する。ただしホワイトボードに書かないと伝えられないものはシンプルなモデルではないかも。
→ 日常的な会話にモデルが出てこないとおかしい。
コアドメインで仕事しているか
- 汎用サブドメインとは他の代替技術があれば置き換えられるもの。
- 支援サブドメインとはコアほど重要じゃないけど必要不可欠なもの。
- コアドメインとはビジネスの核心であり、システム価値を整理することでコアドメインで仕事しているか否かがわかる。
- インセプションデッキやPRDとシステム価値は同様の事柄が記述されるはず。
コンテキストモデル
- 利害関係者や外部システムとの関係を洗い出す。
- 利害関係者が満足する要件は何か→その要件を満たすドメインモデルって何という感じでRDRAとDDDは直に繋がっている
要求モデル
BPStudy#145〜進化する要件定義(RDRA meets DDD)に行ってきました(第1部)
RDRA2.0とは
神崎善司様(@zenzengood)
感想
神崎様のRDRA2.0のお話はRDRA2.0の紹介と体験ワークショップに参加させていただいた際に伺ったことがあったのですが、数ヶ月経ち実際に業務で使ていくうちに浮かんだ疑問が今回の発表で解消されました。
業務で使っていている中で浮かんだ疑問点とそれに対する解決策は以下です。
- 既存の案件に適用した際に依存の外側から順番に書いていこうとすると、既に開発してきていて合意が取れている部分についても作図していく必要があり今フォーカスしたい部分に注力できない。
- ユースケースレベルの粒度で洗い出せれば良いところを情報/状態モデルまで作図する必要があると感じてしまう(これに関してはその時点で必要ないものについては書かなければよかったのですが、熟練しない内には型を破りたくないという私の趣向もあります)。
→ 外側のレイヤーから説明しているが必ずしもその説明した順番で記述する必要もなく、あくまでRDRAでは合意というのを大切にしているので合意が取れているのであれば必要のない図をわざわざ書く必要もなさそう
- 概算見積もりにRDRAを適用していくイメージがつかめていなかった。
→ 重要なアクターに紐づくユースケースへと落とし込み、そのユースケースの数で概算見積もりを出す。より精度の高い見積もりが必要な場合はユースケース毎に画面等のブレークダウンした図を作成していき算出する。
また、前回の発表では一度に理解しきれなかった部分についても改めて聞くことで学び直しになり勉強になりました。
神崎様、ありがとうございましたm( )m
以下メモ
RDRAで解決したい世界
- コンサルで苦労した要件定義をスムーズに進めたいのがモチベーション
- 従来の要件定義では要件を決める人とその要件をまとめる人が分かれていて、要件を決める人が出したAsIsの資料をもとに要件をまとめ、レビュアーにレビューしてもらうで要件の決定がなされる。また、従来の要件定義にあるガントチャートについてはガントチャートを書く→計画どおりに行かないので人数を増やしてスケールさせる→するといきなり並行作業が始まって全体をわかっている人がいなくなりがちという問題がある。
- アジャイル開発においても、最初は重なる部分が少ないがスムーズに開発が進んでいるように見えるが、結合が始まる中盤以降で手戻りが多くなってきて新規開発にリソースを割けなくなりバックログが減らなくなるという問題がある。
- 保守開発においても品質の悪化が見られる。それは要求を出す人と実装する人が分かれているので影響度分析ができなく、また頼りになるドキュメントがなく頭の中の記憶が頼りになるため。システムの可視化を管理者がしたくても最新の状態をドキュメントとして維持できない。
上記の問題を解決することがRDRAのモチベーション
システム化に関わる要素
システムからシステム価値の方向へ依存している。 例) 画面のいるいらないはどうシステムを使おうと思っているのかがわからないと検討のしようがない
RDRAって何かを端的に理解するにはRDRAレイヤーのスライド一枚を参照する。
アイコンの関係
- 文章ではなくアイコン間の線のつながりでWhyを表す。
- システムの外部環境には業務フローと利用シーン、ビジネスユースケースが含まれる。業務フローで表現できない場合は利用シーンとして箇条書きで表す。商品のカテゴリ、取引先のカテゴリがあってある取引先に対するあるカテゴリの商品は1%割引のような組み合わせ間の条件をビジネスルールとして表で表す。
- システム境界におけるイベントはファイルやり取りでもAPIでもOK。 なぜなら RDRAではHowを取り扱わない。WhatとWhyだけ 。 なぜHowを取り扱わないかというとHowを扱い出すと手が止まるから。
→ RDRAではスピード感のある合意を大切にしている
- 情報モデルはビジネスを駆動する用語。
- 状態モデルも情報モデル同様ビジネスを駆動する用語ではあるが、なんらかの動作を伴った結果。
ダイアグラム
- システムコンテキスト→要求モデル→ビジネスコンテキスト→ビジネスユースケース→業務フロー利用シーンバリエーション→情報状態モデル→UC複合図 の順番で説明しているが、 必ずしもこの順番ではなく必要もなく、必要のないものは書かない 。
- 一覧はRDRAのモデルを使えば後から生成できるので最初から一覧は作らない。合意の前に一覧にするということは色々先に決めてしまっていることが多いので注意。
- 文章からではなくモデルのつながりで表現していく(文章と同じような表現力がある)
- みんながドキュメント書き始めると関係がわけがわからなくなるのでみんなで図を書く。RDRAでは基本的に文章は書かない。最初から文章で書くと後から時間がなくて直さなくなり、いらない機能を作ることになりがち。
- プロジェクトの特性に応じて使い分ける。 全部のプロジェクトで全部の図を書くわけではない 。アジャイル開発等ではある程度図を書いたら開発に入ったほうが良い。
- システムの今を見られるので、保守開発とかで担当者ごとにバラバラのことを言っているのを防ぐことができる。
- ブレークダウンしていく際は、ビジネスコンテキストの業務→ビジネスユースケース→業務フローという順番。これらをつくるとシステムの大体のスコープがわかるので概算見積もりを出せる。ただこれだけだと精度がわるいのでユースケースごとに画面とかを考えていくと精度を上げられる。
ダイアグラムの関係
- システムコンテキストについては要件定義メンバー全員で認識合わせ。ただこれに時間かけてもしょうがないので30分程度でぱぱっと作る。
- 要求モデルについては重要なステークホルダーと紐付いた要求リストを洗い出す。重要じゃないステークホルダーに紐づく要求は一旦切り捨てる(本当に重要ならまた話に上がってくるはず)
- 1個1個の図を丁寧に作るのではなく、作れなかったらさっさと次に行く。現時点でわかることをできるだけ図に起こしていき、わからないことは一旦おいて次に行くイメージ。ヒアリングした要望がどこのモデルに属するのかを識別して書いていく。
- 状態を変えるのはユースケースなので状態はユースケースにつなぐ
- システムコンテキストは最初から書けない。色々な図を書いていく上で見えてくる。
- 要求モデルもきちんとやろうするとすごい時間かかる。重要な要求を10個くらい整理していつでも見れるようにする。一覧100個もあるようなリストを作るとかやりがちだけど全部拾おうとしたらダメ。重要なもののみ救う。
- 要求モデルは必ず作るわけではなくエクセルの一覧とかあるならそれにアクターくっつけて大事なもののみ拾う。
- ビジネスコンテキストはリッチピクチャーよりちょっと引いて俯瞰してみたもの
- システムの肥大化はビジネスユースケースでコントロールできる。何でもってビジネスユースケースを分けるかが大事。どのようなものを使っていてビジネスを回していて、 ビジネスユースケースが異なるということは何の差があるのかがわかるものを紐付ける ←これがビジネス要素
- ユースケースに関わる画面や状態等を集めてきて結び付けているのがUC複合図
- 状態モデルのユースケースこそ整合性の観点で重要。照会だけするユースケースとかは状態モデルに出てこなく、整合性という観点のみでいえばそんなに大事じゃない。ユースケース、情報、状態は繋がっている。ただ毎回やるのは大変なので毎回やるわけではない。 本当に精度が欲しいときだけあってユースケースさえ出れば良い時はやらない 。
- 入出力、状態、バリエーションがビジネスでよく変わる。データ変えろってことはあんまりない。そこが変わるとどのユースケースにどういう影響が出るかを追跡できる。
RDRAが目指すもの
- アイコン間のつながりが妥当かどうかで整合性が取れているか否かを判断する。
例)魚屋で寿司屋くれっていったらん?ってなるけどまぁなくもなさそう。ただ自転車くれって言ったら明らかに変なのでその温度感で業務に対しておかしいかどうかをつながりから判断する。
網羅性はアクターからはいってアクターに出ていくかどうかをみる。
- 整合性も網羅性もつながりで説明できることで担保する。
- 既存システムの可視化という観点では、1つの図を見て認識を合わせる。ドキュメントかっちり作るということではなくてある程度の粒度でもってコミュニケーションできる図をつくりましょうという話
ドメインモデルとの関係
- RDRA的にはDDDと繋げてもつなげなくでもどっちでも良い。Howを取り扱わないので。
- RDRAは外側から枠組み固めていくイメージ。DDDは内側から育てていくイメージ。タイムボックスで両方回していくのが良いのでは。
Puppeteer + TypeScriptでUIのテストを行う
設計の勉強会だったりbuildersconだったりで刺激的な話たくさん聞いたりできたりして、書きたいことはたくさんありますが結構文量がいる話で、普段の業務の忙しさにかまけて何もアウトプットしないということになりがちなので普段の業務で使っているようなライトなものでもアウトプットしていこうと思います。
Puppeteer + TypeScriptのテンプレート
画面があるアプリケーションを業務で作っていると粒度の大小はあれ手動や自動化などでUIのテストを行っていると思います。
そんな後者を便利に行えるツールでPuppeteerがありますが、私はチーム開発では型が欠かせないと思っているのでTypeScriptで書きたくなります。
そんなPuppetter+TypeScriptですがプロジェクトごとに都度用意するのはめんどくさいのである程度まで下処理してあるtemplate的なものをよく自分のGithubにあげています。
それがこちらです。
yarn
を叩いたあとにyarn test
を実行すればsampleのテストが1つ走ることの確認ができますので、確認ができたらあとはxxx.test.ts
をお好みで作っていただいてガツガツ書いていくだけです。
どこかで誰かの役に立てば幸いです
値オブジェクトの悩みポイント:どこまで型を用意するか / nullableな値をどう取り扱うか
ライト版はこちら
早速ですがドメイン駆動設計に関係するいくつかの書籍でも紹介されている、「人名」を考えます。
「名前」と「名字」は確実に存在し、「ミドルネーム」無い場合もあるという想定です。
public class PersonName { private <Type> firstName; private <Type> lastName; private <Type> middleName; ... @Override public String toString() { return String.format("%s %s %s", firstName.toString(), middleName.toString(), lastName.toString()); } }
このときそれぞれの型はどのようにするのが良いでしょうか。
Stringを採用
public class PersonName { private String firstName; private String lastName; private String middleName; ... }
最も簡単な方法です。
「人名」という値オブジェクトを用意し、「名前」や「名字」はその構成要素でしかないという考え方です。
「名前」や「名字」単体でのでの利用がない場合はこのような設計がシンプルで良いかもしれないです。
メリット
- 型が増えなくて済む
- 取り回しが効く
- 「人名」の生成時に渡す引数が簡単
デメリット
- 「名前」、「名字」、「ミドルネーム」それぞれの個別の振る舞いは表現できない。
- 「人名」の生成時に「名前」と「名字」が存在すること、「ミドルネーム」がnullではないことを担保する必要がある。
- 型で「ミドルネーム」が空の可能性があることを表現できていない。
String + NonEmptyStringを採用
public class PersonName { private NonEmptyString firstName; private NonEmptyString lastName; private String middleName; ... }
Stringのみと同様、「人名」という値オブジェクトを用意し「名前」と「名字」についてはその構成要素でしかないという考え方です。
値が空に可能性を明確に排除しているNonEmptyStringという型を用意することで通常のStringで値が空の可能性があることを示唆しています。
メリット
- String同様型が増えなくて済む(NonEmptyString1個だけ)
- 取り回しが効く
デメリット
- 「名前」、「名字」、「ミドルネーム」それぞれの個別の振る舞いは表現できない。
- 「ミドルネーム」がnullではないことを担保する必要がある。
- 「人名」生成時に渡す引数がStringのみと比べて複雑になる。
FirstName / LastName / MiddleNameを採用
public class FirstName { private static final int MIN_LENGTH = 1; private static final int MAX_LENGTH = 50; private String value; // コンストラクタや生成メソッドで検証するか利用側で検証してから渡すかはまた別の悩みポイント… ... @Override public String toString() { return value; } }
public class MiddleName { private static final int MAX_LENGTH = 100; private String value; // コンストラクタや生成メソッドで検証するか利用側で検証してから渡すかはまた別の悩みポイント… ... public boolean isSpecified() { // valueが空文字での生成は許してもnullでの生成は許さない必要あり return !value.isEmpty(); } @Override public String toString() { return value; } }
public class PersonName { private FirstName firstName; private LastName lastName; private MiddleName middleName; ... }
「名前」、「名字」、「ミドルネーム」を表す値オブジェクトをそれぞれ用意します。
メリット
- 言葉と1対1で対応する
- 個別の細かな性質や振る舞いもコードで表現することができる。
- 型が言葉そのもので表されているので意図が明確。
デメリット
- 型がユビキタス言語の数だけ増え、取り回しが効かない。
- 似たような内容の型が増える
どれを採用するのが良さそうか
その業務でどう取り扱いかによると言ってしまえばそれまでなのですが、私の場合は「名字」「名前」でそれぞれ個別の性質や振る舞いがあるか否かを考えて、 「命名された文字列を表す」より更にならではの振る舞いがありそうな場合は、FirstName / LastName / MiddleNameを採用し、そうでない場合はただの構成要素なのでStringを採用します。
今回のケースでは「ミドルネーム」という概念が登場した時点で「指定がないことがある」というならではの振る舞いがあることは想像できるため、Stringのみのパターンの採用は見送ります。
String + NonEmptyStringとMiddleNameのどちらを採用するのかは悩みポイントですが、「指定がないこともある」という性質も踏まえて「ミドルネーム」という概念だと考え、MiddleName型を採用するのが一番素直に思えます。
「名字」「名前」についてはString、MiddleNameだけを値オブジェクトとして表現するハイブリッドなパターンも考えられますが、振る舞いを表現する場所が構成要素毎にまちまちなのが気になるため採用を見送ります。
Option VS. 値オブジェクト単体
JavaのOptionalなどでnullである可能性を表現できる型を用いるか、値オブジェクト単体で空である可能性も表現するかも悩みポイントです。
今回のケースでは「指定がないこともある」という性質自体が「ミドルネーム」という概念であるという考え方で、私の場合はMiddleNameを採用しOptional
また、指定されていないことの表現は意図していないミスを防ぐため極力nullを避け、文字列ならば空文字で表現したい気持ちがあり値オブジェクト単体での表現を採用します。
終わり
今回検討した内容は正解がなくケースバイケースで様々な答えが考えられると思います。
様々な意見がある中で、どうしてそのようにしたかという考え方についてフォーカスして色々な方の話を伺いたいです。
BPStudy#141〜DDD(Domain Driven Design)実践の現場に行ってきました
先日開催されたBPStudy#141〜DDD(Domain Driven Design)実践の現場に参加してお話を聞いてきました。
話を聞きながら、メモした大事そうなところを整理しながら共有できればと思います。
ドメイン駆動設計の正しい歩き方〜どこに焦点を合わせ、どう実践するか
増田さん(@masuda220 )
ドメイン駆動設計でなぜつくるのか?(p.2〜p.3)
- 進化を続ける、変更が楽で安全なソフトウェアを手に入れるため
- 単に動くだけのソフトウェアにしないことに振り切っている
- 変化しなくてもいいソフトウェアだとフィットしないかも
ドメイン駆動設計とはなにか?(p.4〜p.6)
核心にある複雑さに立ち向かう(p.7〜p.10)
- Evansさんはソフトウェアの複雑さはたくさんあるけどなかでも複雑こそがビジネスの複雑さが根本原因と言っている
- Evansさんの考え方はここに立ち向かえばソフトウェアを整理できるという考え方
- ビジネスルールが特にソフトウェアの複雑さにダイレクトに効いてくる
核心にある複雑さを適切に扱う(p.11〜p.12)
- 核心とそれ以外の部分が明確になって整理できる
- 周辺(入出力)の複雑さが軽減される
- 全体が整理されていく
核心にある複雑さをどう扱うか 6つの問い(p.13〜14)
上記の3つだけやっていてもダメ…
チームの基本のこだわりポイントにこれらを置いて毎日続けているかがドメイン駆動設計をきちんとやっているかの指標。
→ 逆にこれを意識してきちんとできて居ればエースエンジニアがいなくても良いソフトウェアになっていく。
正しい道からはずれるとき(p.15〜p.17)
- ビジネスの活動から目をそらす(パフォーマンスチューニングに注力しすぎたり)
- 全体を均質にカバーしようとする(どこでも値オブジェクトやEntitynなどのドメイン駆動設計の戦術パターンを取り入れようとする)
→ コアのところだけを頑張る。メリハリをつける。コアじゃないところは手を抜く。
- ビジネスを表面的に捉えて理解した気になる
→ ビジネスの用語を意識していなかったところからだんだん使うようになってくるとやった感が出てくる。学習曲線の1つ山越えたとこ。その段階でビジネスのキャッチアップをできた気になり、ドメイン駆動設計を行っている気になっていると得るものが少ない
- 入出力の関心ごとをドメイン層に持ち込む
→ DBの都合はドメイン層に関係ない。普通はドメイン層のモデルを再生成しようと思ったら様々なテーブルから情報をかき集めてきて結合する必要があるはず。1つのテーブルの情報で済むならそれはコアドメインではない
- モデルと実装を切り離す
→ モデリングができるようになって楽しくなってきたときにやりがちなのがソフトウェアの実装に役に立たないことにもフォーカスしてしまう。
→ 実装のためのモデリングはどうしても細かい部分でスッキリしないことが多い
→ 綺麗すぎるのは危ないかも
- システム間を力づくで連携させる
→ 訳のわからないファイル読んだり、段々APIに項目追加されてきたり、APIで条件に応じて違うデータ返さなきゃいけなかったり…
→ システム間を繋げられてしまったらそこで進化が止まってしまう。常にもっと良い繋ぎ方があるんじゃないかと考えるべき。
ソフトウェアの核心にある複雑さに立ち向かう(p.17〜p.18)
- 青い項目(コアドメインに集中する、ビジネスを深く洞察する、システム間の秩序の改善を続ける)が肝
具体事例(p.19〜p.21)
DDD Allianceさんで開催しているドメイン駆動ワークショップのお題
- P.21のような但し書きがいっぱいの複雑なルール
複雑な料金計算ロジックをどうやってコードで表現するか(p.22〜p.24)
- ドメインロジックをまず隔離する
→ 画面の関心ごとと実際の計算ロジックを分離する
→ ビジネスルールだけで開発してそこだけでテストできるように開発させるという意味で、独立した存在として取り扱えるよう開発する
oO チームごと分けられるようにするくらいの意味合いかも
- 自然言語や数式、クラス図などを用いて構造、要素を整理する → コード書いてみる → うまくいかなかったらモデルにFBする → またコードを書いてみるという感じで行ったり来たりする
- 最初から良いモデルを作るのは無理。モデルとコードはズブズブの関係
コアドメインに集中する(p.25)
- 例えば、どう考えても幼児の寝具が料金計算の軸になってることはない
→ 主軸の取り方考える。(部屋のグレードなのかシーズンなのか)実験的にやってみてコードでうまく表せたらOK。
→ うまくいかなかったら軸の取り方を変えてまたやってみる。実験してやってみる方が早い
ビジネスを深く洞察する(p.26)
- 開発者が料金表にタイポがあった場合に指摘できるか。歯抜けが料金があったときに仕様を補完して提案できるか。
→ これが出来るほどビジネスを理解していると後から変更したいという要望があっても反映しやすくコミュニケーションロスも少なくなる。
→ そういうレベルで自分たちが業務を理解していないんじゃないかという意識を常にチームで持ち、互いに声をかけていく
システム間の秩序の改善を続ける(p.27)
- 外部の予約サービスではこの複雑なプランを表現できないのでどう簡単化して外部予約サービスで表示するかというのが課題になる。
→ 周辺のサービスなどの状況を俯瞰して把握することでコアのドメイン、サービスが締まってくる
ビジネスの活動を継続的に学ぶ(p.28)
上記の3項目(コアドメインに集中する、ビジネスを深く洞察する、システム間の秩序の改善を続ける)を行っていくためには必然的にビジネス学ぶことになる。
ドメイン駆動設計を現場に導入する(p.31〜p.32)
- 体験的に習得する
→ 大事だけど苦労するところ
- Evans本を読む
→ 特効薬じゃないけどじわじわ効いてくる。設計の質が変わってくる。時間のかけ方が変わってくる。ただし読みにくい→Evansの文章スタイルに立ち向かう
想定読者の要件をクリアする(p.33〜p.34)
→ 2003年くらいのオブジェクト指向の知識はむしろ捨て去った方が良いかも * オブジェクト指向設計の文献
→ 有名どころだと寧ろEvans本より鈍器で敷居高い
想定読者の要件をクリアする教材セット(p.35〜p.38)
→ 現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法の補足
Evans本をちゃんと読む(p.39〜p.49)
- 行ったり来たりするために紙の本を推奨
- あとから確認したり検索するために電子版もあると良い
- まずは28ページの抜粋版から読んでみる
→ どういうことを注力したいかということがわかる * IDDD本はEvans本の一部をピックアップして書いている本だというのを分かった上で読むのがオススメ
→ IDDD本で紹介されていない71のセクションにも宝物が埋まっている
Evansの文章スタイルになれる(p.50〜p.51)
- 本の中盤にある設計課題と考え方の説明を読んでから前の方にあるプロジェクトの経験談や具体例を読んだほうが理解が深まる
質問
- Q.ドメインエキスパートの説明力足りない場合どうしているか?
A.基本的にドメインエキスパートの説明が足りていることなんてない。具体例持っていくとよく話を引き出せる。わざと間違った具体例を持っていっても良い感じに話してくれる。スタートアップだとエキスパートいないのでみんなで考えるしかない。逆に自分が興味を持てない仕事はしない。
- Q.ドメインエキスパートが決定権を持っていない、アクセスできない場合どうする?
A.ドメイン駆動設計をやった手応えの1つで変更が楽だと仮の決定でコードを書くハードルが低くなる、抵抗がなくなる。確定したらそれに合わせるというのがやりやすくなる。
- Q.ビジネスルールが複雑になるのはなぜ?
A.ビジネスルールの複雑さに立ち向かうを参考にしてみると良いかも
感想
スライドだけでは説明しきれいない補足的な内容について口頭でお話されていて、そのお話の中にも勉強になる事柄が散りばめられていました。
技術的なパターンセットとしてではない、ドメイン駆動設計の心意気、考え方の部分というのを増田さんの言葉でお話していただいて、自分の実体験や本を読んだ知識としてしか知らなかった部分とリンクさせながら聞けて勉強になりました。
DDD Allianceさんで開催されていたドメイン駆動ワークショップに参加したときのことも思い出し、今回のお話を踏まえながら社内などでドメイン駆動設計を体験してもらう場として同じお題でワークショップを開催してみたいなというモチベーションにも繋がりました。
また、Evans本についてもお話いただいた要点や読み方を参考に再度読み直したいと思います。
大変貴重なお話ありがとうございました。
モデル駆動設計によるビジネスをソフトウェアに落とし込む1つのやり方
高崎さん(@ken_takasaki) speakerdeck.com
- 工業的にではなく工芸的につくるのがドメイン駆動設計なのでは
背景(p.8〜p.11)
ドメインの背景を知る
アクティアさんはJava×DDDの会社
なぜプロジェクトは炎上するのか(p.12〜p.15)
- 様々な理由があるけど技術的に複雑なものをシンプルに持っていくことができれば
モデリング(p.16〜p.19)
- ある物体や事象について簡略化した物を作ること
- モデリングを通じてビジネスとソフトウェアの乖離が見つかる。
- エンドユーザにコードを読んでといってもむりなので中間成果物がいる。それがモデルになるという取り組みを行っている。これによりモデルと実装が分離しない
ドメインの用語を理解する(p.20〜p.29)
→過去にあった2001年ごろ。UMLをつかってかいていく。
- 言語の歴史は抽象度が上がっている
- 廃れた
→ 何故か: 仕様や思想がふわっとしている。説明自体もふわっとしている
モデル駆動開発のいいところ(p.30〜p.41)
- ビジネス要件とプログラムの分離
- プログラムの均質化
- 自動生成による生産性の向上
当初のモデル駆動開発はグラフィカルだとぱっと見わかりやすいけど差分管理しんどい、動的振る舞いの表現難しい
→ 良い設計はなんだろうと考えドメイン駆動設計にたどり着いた
今はMarsという自動生成のためのプラットフォーム作っている
言葉を共有(p.42〜p.48)
通じない思い
DDDにはたくさんの言葉
- ドメインエキスパートと開発者の間で普通は乖離があり通訳するのに労力がかかる
→ ユビキタス言語で共有。言語に問題があれば代わりとなる言語を探してモデルを更新する
用語集を作るわけではない。その用語が浸透しきっている状態がユビキタス言語
ユビキタス言語やらかしたあるある(p.49〜p.53)
① 用語集を作る。メンテされない ② ドメインを集めて共有するために壁一面にユビキタス言語貼っていこうという試みを行う
→ 最初に自身が貼ってからだれも追従してくれず…
→ 結局浸透していないから
対話でユビキタス言語(p.55〜p.65)
対話をするためには
一般業務知識を学ぶ → 業種そのものを学ぶ → 顧客のドメインを学ぶのが大事
海図の販売管理の例
一般業務知識を学ぶ
→ 業種そのものを学ぶ。Webで調べる。実物をもらう。
業務を整理するときの手法
→ RDRA
区分を発見した実例
言語IDを用いてソートしたいなどの要件があった
→ 国とか商品とか様々な区分が含まれているように見えるが実際現場では言語IDとして取り扱っているので同じようにそう扱う
ユビキタス言語の選択をミスした実例
船主
→ よくよく考えたいったら顧客という用語が適切
→ かっこいい言語につられて失敗した例
ユビキタス言語は値オブジェクトになる
ユビキタス言語を表現することで概念や用語がソースになり顧客とエンジニアの間で話が通じやすくなった
貧血との戦い
抜けられない染み付いたやり方
ドメインモデルやらかしたあるある
→ テーブルから入るとそのデータ構造に引っ張られる
→ 結果ドメインモデル貧血症に
→ 貧血症にハマることは通る道なのでその後どうするか
ビジネスルールに集中する
→ ドメインだけでビジネスルールをまとめていく力をつける 見積伝票モデルの例)
値引きや為替というのを切り出してドメインに隔離
→ 隔離前のシステムにはなかったルールなのでお客さんにもFBを出来た
ビジネスルールをどこに持つか?
- 数量がビジネスルール知っているのは微妙
- 明細金額が数量と定価を知っているというように変えた
貧血とビジネスルールと日々格闘
感想
ユビキタス言語やドメインモデルの育て方などの話を現場の実体験をベースにお話しいただきました。
実際取り組んでみてどうだったというあたりや、こんな発見があった、こんな失敗をしたという生の話を聞けて大変勉強になりました。
特にユビキタス言語の深め方のあたりは前半の増田さんのお話を含め通じて今回の勉強会に参加して、次にフォーカスを当てて取り組んでいきたいという部分のお話だったのでかなり刺さりました。
お話の仕方自体も洗練されていて聞き入りました。
懇親会でも現場や実例の話を更にお話いただいて、非常に勉強になりました。
大変貴重なお話ありがとうございました。
最後に
今回の勉強会参加して、ドメイン駆動設計についての特に戦略的な話のところの理解がぐっと深まり、モチベーションも更に上げられるいい機会となりました。
お話いただいたお二方、企画、運営をしていただいた関係者に皆様、会場を提供していただいたPixiv様、大変貴重な機会をありがとうございました