前書き
GWに読んだ本、せっかく読んだので忘れないようにBlogにまとめようと思った。
著者:増田 亨
感想
今まで自分が4年間開発してきたシステムはオブジェクト指向の顔をした手続き型だったんだなと思った。簡易ドメイン駆動モデル(DDD)だとは聞かされていたが、オブジェクト指向からは離れた手続き型であることを思い知らされてむなしくなった。
これを機に、とりあえずオブジェクト指向の扉を開きたいと思った。
この本はオブジェクト指向というかなり広い概念について網羅的にかかれている。GWの前半にDDDの本を読んだけどそれよりはすぐに実践するというより、こういう考えをもって開発しよう、プロジェクトを始めようといったニュアンスが強いかも
学んだこと
- とにかくドメインモデル(エンティティ)にはフィールドだけでなく、ロジックも束ねてまとめる。ドメインモデルをデータとロジックのセットで考える
ドメインサービスといった楽なサービスを頼らず、なるべくドメインモデル内に書くことを心掛ける - 三層アーキはドメインモデルを含めた三層アーキ+ドメインモデルを基本構成とする。
- repositoryはDBに依存せずにドメイン毎に作る。DDDっぽい書き方だと、repositoryとその実装クラスのdatasourceはドメイン毎にクラスを切って、datasource内のDBアクセスを実際のDBに即したDBに登録する感じにする
例えば、注文と注文の詳細情報の2つを管理するテーブルに対して、注文登録というユースケースを実現する場合、注文テーブル・注文詳細テーブルそれぞれに対してrepositoryを切るのではなく、repositoryはあくまで注文クラス1つだけにし、その実装クラスであるdatasourceで2つのテーブル(注文・注文詳細)に対してinsertするようなロジックを記載する
以上の3つが学び。
以降では、それぞれの章で学んだことを記載する
第一章:小さくまとめてわかりやすくする
変更が大変なプログラムの特徴
- メソッドが長い
- クラスが大きい
- 引数が多い
変更が楽になるプログラムの書き方
- わかりやすい名前を使う
量をaやb、q、qtyと書かずにquantityとかく - 長い処理をまとめる、空行を使う。切る
- 目的ごとに変数を使う
- メソッドに切る
- 重複した処理をなくす
- 狭い関心毎に特化したクラスを作る
基本データ型を使わずに、値オブジェクトを作る
値オブジェクトとは、フィールドを1つや2つだけ持った小さなクラス。そこに基本データ型だけではチェックできないことをチェックする。
例えば、郵便番号をただのstringにするのではなく、郵便番号クラスを作ってハイフンの前後で別のフィールドを定義するよな感じ。
⇒ただ個人的な感想では、Spring的にはBeanValidationを使えば値オブジェクトはいらないかなぁという感想。何か不具合のあるデータはだいたい登録系でBeanValidationつけれると思うから
ファーストコレクションにする。ファーストコレクションとはリストやコレクションを使わずに、リストを1つだけフィールドにもったクラスを作る。リストへの操作は全てこのクラスを介して行うようにする。そうすることでリストへの変更操作をクラス内に閉じ込める
第二章:場合分けのロジックを整理する
ifの処理をメソッド化する
elseを使わない。ガード節、早期リターンをする
条件に従ってインスタンスを変化させたい場合はIFを使う(多態)
enumを使って状態遷移を明確にする
第三章:業務ロジックを分かりやすく整理する(大事)
データクラスの色々な呼び方
- DTO・・・サブシステム間でデータをやりとりするための設計パターン
- Entity・・・DBとデータをやりとりするためのデータの入れ物
- Form・・・画面とデータをやりといするためのデータの入れ物
- JavaBean・・・開発ツールやフレームワークを意図して制定された共通のデータアクセス仕様に準拠したクラス
業務ロジックを重複させないための設計
- メソッドをロジックの置き場所にする
- ロジックをデータを持つクラスに移動する
- 使う側のクラスにロジックを書き始めたら設計を見直す
- メソッドを短くしてロジックの移動をやりやすくする
- メソッドでは必ずインスタンス変数を使う
- クラスが肥大化したら小さく分ける
- パッケージを使ってクラスを整理する
三層アーキ+ドメインモデル
- プレゼンテーション層・・・UIなど外部との入出力を受け持つ
- アプリケーション層・・・業務機能のマクロな手順の記述
- データソース層・・・データベースとの入出力を受け持つ
- ドメインモデル・・・業務データと関連する業務ロジックを表現したドメインオブジェクトの集合
第四章:ドメインモデルの考え方で設計する
特になし
第五章:アプリケーション機能を組み立てる
SpringFrameworkですぐ実現可能。
サービスクラスの設計はごちゃりやすい
- ドメインオブジェクトが業務ロジックの置き場所として十分機能していない
- プレゼンテーション層の関心毎に振り回される
- DBの入出力の都合に引きずられる
ユースケースの複合系は小さなAPサービスとそれを活用する大きなAPサービスに分ける⇒ただトランザクションがちょい気になる
第六章:データベースの設計とドメインオブジェクト
オブジェクトとテーブルは別物
UPDATEをしない!?
第七章:画面とドメインオブジェクトの設計を連動させる
タスクベースのユーザインタフェース・・・Amazonの商品購入までのプロセスのようなもの。商品購入までには①購入者の情報入力②商品の登録③決済方法の登録④配達手段の登録 など複数プロセスにわたって必要事項を入力しなければならないが、そのすべては同時に行う必要はなく、事前に1つ1つ行っておくことが出来る。用途に特化した小さな部品に分解すること
画面表示項目用の数字のカンマ区切りやフロントエラーメッセージ、cssのプロパティなんかも業務ロジックが入っているんならバックで返却すべきという考え
⇒これはさすがに面倒だと思う。
第八章:アプリケーション間の連携
アプリケーション間の連携方式
- ファイル転送
- DB共有
- WebAPI
- メッセージング(非同期通信・ソケットAP?)
使いにくいWebAPI
- データを取得するために指定するパラメータが多い
- 取得したデータの項目数が多い
- 登録時に指定しなければいけないデータ項目が多い
REST Controller
SwaggerUI
複雑なWebAPI
第九章:オブジェクト指向の開発プロセス
書かれていること:ウォーターフォールではオブジェクト指向無理や、アジャイルやろう。どんだけ手の込んだ設計書作っても開発者が設計者と違うのならいいものができるわけないし、後工程の変更でどうするの?設計と開発は一緒にやろ
第十章:オブジェクト指向設計の学び方と教え方
書かれていること:オブジェクト指向の効力を感じれるのはリリース後の改善活動をしているとき。まずは今作っているコードを改善しよう
- 重複したコード
- 長いメソッド
- 巨大なクラス
いい本
- 「リファクタリング 既存のコードを安全に改善する」 著Marthin Fowler
- 「ThoughtWorksアンソロジー アファイルとオブジェクト指向によるソフトウェアイノベーション」 著ThoughtWorks
- 「実装パターン」 著Kent Beck
- 「オブジェクト指向入門」 著Bertrand Meyer
- 「エリックエバンスのドメイン駆動設計」 著Eric Evans