Contents
スポンサーリンク
概要
オライリーの「現場で役立つシステム設計の原則」を読んだので感想を書こうと思います。
スポンサーリンク
書籍概要
どんな本?
「ソースがごちゃごちゃしていて、どこに何が書いてあるのか理解するまでがたいへん」「1つの修正のために、あっちもこっちも書きなおす必要がある」「ちょっとした変更のはずが、本来はありえない場所にまで影響して、大幅なやり直しになってしまった」といったトラブルが起こるのは、ソフトウェアの設計に問題があるから。日本最大級となる60万件以上の求人情報サイト「イーキャリアJobSearch」の主任設計者であり、システム設計のベテランである著者が、コードの具体例を示しながら、良い設計のやり方と考え方を解説します。
- 増田亨 著
- 2017年05月 発行
- 320ページ
- 定価3,234円(税込)
スポンサーリンク
内容のまとめと感想
DDD(ドメイン駆動開発設計)をベースにしつつ、オブジェクト指向、DBやREST APIなど、幅広くシステム設計における設計のノウハウを説明している書籍です。
コード例で使用する言語はJavaでフレームワークはSpringを使用していますが、Springに依存する部分の説明はそこまで無いので気にしなくても良いと思います。
特徴
文章多めで丁寧な説明
文章が多めで、説明を丁寧に行っていてコードの例は分量的には少ないです。
ですので前述の通りJavaが使用されていますが、特定のプログラミング言語に依存せずに読む事ができるのではないかと思います。
日本人著者による書籍なので、オライリーの翻訳本のような違和感が無いのも良い点です。
DDD以外の領域も説明
DDDを使用した設計の説明が本書のメインとなっていますが、後半は設計したドメインオブジェクトとシステムとのやりとりのノウハウに関して説明されています。
(まとめの後にある、個人メモ内で多く触れています)
具体的にはテーブル設計、画面との連携、REST APIとの連携など、実際に多くのケースで考慮が必要となる部分の説明がされています。
画面との連携では、ドメインモデル側に表示するメッセージを持たせた方がコードの見通しが良くなるなど、独自(?)の説明もあって興味深いです。
情報の並び順やメッセージなど、情報表示に関係する部分もドメイン側のロジックに持たせるべきという、本書の主張はこれまであまり見かけた事がありません。
このあたりは賛否両論になりそうで、理由を聞くとなるほどと思うこともありつつ、個人的には判断が難しいと感じました・・・。
DDD自体を既に他の書籍等で学んでいるという方は、前半部分は既出な内容が多くなってしまうので、その点は注意が必要です。
まとめ
DDDの考えをベースにしつつ、幅広くメンテナンス性の高いシステム設計に必要となる原則を多く説明している書籍でした。
DDD自体を全く学んだ事が無いという人であれば、読みやすく基本を理解するのに良さそうです。
ただしDDDの説明が本書の半分以上を占めていますが、ドメインサービスなど全ての要素に関して説明があるわけでは無いです。
DDD自体を深掘りしたいという方は、別途DDDに関する書籍で知識を深めた方が良いと思います。
コードレベルでDDDを学ぶ事ができる下記が個人的にはオススメです。
個人的メモ
コトに注目するデータベース設計
業務アプリにおける中心の関心事項は「コト(事象)」の管理で、参照や記録のためにDBや重要となる。
コトは主体(ヒト)と対象(ヒトやモノ)との関係性も併せて記録する必要があるので、外部キー制約によって、これらの関係性も併せて正確に記録する事が大切。
記録のタイミングが異なるデータはテーブルを分ける
記録のタイミングが異なるデータを1テーブルで管理するとNULL可能なカラムが必要になる。
記録の変更を禁止する
UPDATEによる過去のコトのデータの更新はすべきではない。
修正したい場合には、取り消しやマイナスといった記録を追加して対応する。
例:取り消しの場合は下記の3つのレコードが作られる
1:元のデータ
2:取り消しのデータ
3:新データ
カラムの追加はテーブルを追加する
カラムを追加は今まで記録していなかった情報を追加できるように拡張することになる。
NULLを許容するか、「虚」のデータを追加する必要がある。
整合性や信頼性を劣化させる可能性があるので、新しい外部キーで連携したテーブル作って対応する方が良い。
コトの記録のテーブルの問題点
テーブル結合や計算などの導出ロジックが必要になって煩雑さが増したり、性能的な問題が生じる。
状態を記録するテーブルをコトの記録と併せて用意する事で解決策の1つになる。
(例:入出金の記録と併せて、残高を状態として記録を行う)
状態の更新は同時に実施する必要はなく、トランザクションを分ける。(非同期メッセージングなどで後から更新するなど。)
状態更新の失敗でコト自体をロールバックしてしまうのではなく、状態の更新単体で検知して対策をする方式にすべき。
画面とドメインオブジェクトの設計を連動させる
画面アプリケーションの開発の難しさ
画面アプリが複雑で変更がやっかいな理由
- 画面そのものが複雑
- 画面の表示ロジックと業務ロジックが分離できていない
よって画面自体を用途ごとのシンプルなものにまとめて、ロジックを分離させる事が重要
画面の関心事を小さく分けて独立させる
複雑な画面は複数の関心事が絡まっているので、関心事を分ける。(タスクベースのユーザーインタフェース)
例:注文画面
- 注文者の特定する情報(氏名や顧客番号)
- 注文した商品と個数
- 決済方法
- 配送手段と配送先
- 連絡方法
=> これらを実現するための巨大なOrderドメインオブジェクトを作るのではなく、個々の関心事のドメインオブジェクトを作り、Orderはこれらを呼び出すだけにする。
画面とドメインオブジェクト
基本的に画面とドメインオブジェクトの関心事は同じで、表現が異なるものである。
なので画面の表示にはドメインオブジェクトがそのまま使えるのが理想であるが、実際には構造や画面固有の表現などがあるため、そのまま使うのが難しい場合がある。
その場合の対策方法としては、下記の2つが対策として考えられる。
- ドメインオブジェクトをそのまま使う => 本書ではこちらを極力採用すべきとしている
- ビュー専用のオブジェクトを作って使用する =>前述のタスクベースのインタフェースが実現できない場合はこちらを推奨
画面の関心とドメインオブジェクトで表現する関心事は一致するのが理想。一致していないならなぜ一致しないのかを分析すべき。
ドメインオブジェクトに書くべき表示ロジック
- 論理的な構造情報
- 段落ごとの文章(stringの配列として保持): pタグなど要素はビュー側が責務を持つ。
- 場合ごとの表示の違い
- データがない時に「見つかりませんでいた。」
- データがある時に「X件見つかりました。」
- ドメイン側で実装する事でビュー側の判断分岐を減らす事ができる。情報の表示は利用者の関心事なのでドメインオブジェクトにあっても問題はない。
画面(視覚効果)とソフトウェア(論理構造)を関係付ける
画面項目の表示順序ドメインオブジェクトのフィールドの並び順、グルーピングなども画面とドメインオブジェクトの不一致になるので揃える事が改善につながる。
(例:Bookという書籍に関するオブジェクトは、画面に表示しない情報まで含んでいる。これをBookSummaryというオブジェクトで必要な情報だけを表示順序で保持する。)