Slide 1

Slide 1 text

その設計つながってますか? 2020/06/18 Naofumi Yasuba GxP Techtalk

Slide 2

Slide 2 text

1 ⾃⼰紹介・経歴 Naofumi Yasuba 株式会社GxP 取締役/開発本部⻑/VPoE/IT Architect 社内PJのリーダー ・要求分析/基本設計 ・業務フロー ・データモデリング ・総合テスト 前職 GxP エンジニア ・Java/Spring ・アジャイル開発 ・オブジェクト指向 ・ドメインモデリング (DDD) アーキテクトとか マネージャーとか ・AWS/GCP/Salesforce ・アーキテクチャ ・CI/CD ・組織運営など何でも

Slide 3

Slide 3 text

2 はじめに ⾃⾝の経験をもとに、設計・実装を⾏うにあたって重要な考え を共有します。この⽅法は「銀の弾丸」ではないので、参考に して⾃分なりの考え⽅を⾒つけてください。 業務アプリという分野においては、業務を理解していない⼈が よい設計・実装はできないと考えています。

Slide 4

Slide 4 text

設計とは

Slide 5

Slide 5 text

4 設計とは システムの仕様や構造などを決定する⼯程 要件定義 設計 実装 基本設計 詳細設計

Slide 6

Slide 6 text

どのように設計するか

Slide 7

Slide 7 text

6 どのように設計するか 1. INPUTとなる要件をもとに、対応内容を考える 要件 設計

Slide 8

Slide 8 text

7 どのように設計するか 1. INPUTとなる要件をもとに、対応内容を考える 2. 適切に区切って、詳細化 要件 設計

Slide 9

Slide 9 text

8 どのように設計するか 1. INPUTとなる要件をもとに、対応内容を考える 2. 適切に区切って、詳細化 3. 詳細化した内容をもとに実装 要件 設計 実装

Slide 10

Slide 10 text

つまり

Slide 11

Slide 11 text

要件 設計 実装 設計を通して、 要件~実装がつながっているはず

Slide 12

Slide 12 text

要件~実装がつながった結果

Slide 13

Slide 13 text

12 要件~実装がつながった結果 要件に合致したシステムを作ることができる • 要件のもれや解釈ミスがない • 設計もれもない 要件 設計 実装

Slide 14

Slide 14 text

13 要件~実装がつながった結果 保守性の⾼いシステムができる • 修正時の影響範囲が特定しやすい • 業務⽤語でコード化されているので可読性が⾼く、背景も理解しやすい 要件 設計 実装

Slide 15

Slide 15 text

現実に戻ります

Slide 16

Slide 16 text

その設計つながってますか?

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

今⽇は、設計を通して 要件~実装をどのようにつなげるか の話をします

Slide 19

Slide 19 text

アプローチ

Slide 20

Slide 20 text

19 アプローチ 要件 設計 設計 実装 Step 1 設計の質を上げる

Slide 21

Slide 21 text

20 アプローチ 要件 設計 設計 実装 Step 2 設計と設計をつなげる

Slide 22

Slide 22 text

21 アプローチ 要件 設計 設計 実装 Step 3 要求と設計をつなげる

Slide 23

Slide 23 text

22 アプローチ 要件 設計 設計 実装 Step 4 設計と実装をつなげる

Slide 24

Slide 24 text

23 アプローチ 要件 設計 設計 実装 Step 5 全てがつながる

Slide 25

Slide 25 text

具体的な考え⽅

Slide 26

Slide 26 text

要件 設計 設計 実装 Step 1 設計の質を上げる

Slide 27

Slide 27 text

26 番号をふる u ドキュメントやコンポーネントに⼀意な番号を割り振る • 仕様書ファイルをソートして整理できる • 表記ゆれによる間違いを防⽌ ‒ 顧客情報参照、会員詳細参照など • サービス名などビジネス都合の変更にも追随 番号を ふる Step1 IF仕様書_A01_顧客参照.xls IF仕様書_A02_顧客詳細参照.xls IF仕様書_B01_顧客情報更新.xls : :

Slide 28

Slide 28 text

27 標準化 u ⽮印や図形の意味をあわせる • ⽮印:時系列的なフローを表すのか、データの流れを表すのか • 図形:同じ種類の形・⾊を持つものは同じような概念か u 配置する場所・順序を整理する • 似たような概念は同じところに。 番号を ふる Step1 標準化

Slide 29

Slide 29 text

28 標準化 u ⼀般的な記法を採⽤する • UML、ER図、BPMNなど。ドロアーツールに対応しているものも多い ‒ astah, EA, gliffy, draw.io, pluntUML, A5erなど • 新規メンバーにとっても理解しやすい 番号を ふる Step1 標準化 システム 〇〇する ××する ユースケース図 アクタ シーケンス図 ER図 ユーザ システム システム ○○テーブル id name : ××テーブル id name :

Slide 30

Slide 30 text

要件 設計 設計 実装 Step 2 設計と設計をつなげる

Slide 31

Slide 31 text

30 レイヤーを表現 u 粒度をあわせ、レイヤーを分けて表現する • 設計書上で表現する粒度は統⼀する。特定の箇所を細かく書きたい場合は レイヤーの違う別の設計書に表現をする • 全体像を俯瞰してみるための資料としても活⽤できる 番号を ふる Step1 標準化 レイヤー を表現 Step2 システム システム構成図 ユーザ IF⼀覧 ID | 機能名 ----+------- A01 | 顧客参照 A02 | 顧客詳細参照 B01 | 顧客情報更新 IF仕様書_A01_顧客参照 IF仕様書 IF仕様書_A02_顧客詳細参照 〇〇アプリ システム構成図詳細 ××バッチ ××バッチ 抽出処理 ロード処理

Slide 32

Slide 32 text

31 関連を作る u 設計図間の関連を明確にする • 例えば、何かの状態をDB更新する処理については、 (1)ユースケース図、(2)状態遷移図、 (3)機能仕様書、 (4)データ更新仕様/データマッピング表 などを番号で紐付けて管理する 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る システム 〇〇する ××する ユースケース図 アクタ 完了 キャンセル 状態遷移図 処理中 機能仕様書 ××機能 1. ・・・ 2. ・・・・・ 3. ・・・ データ更新仕様 △△テーブル No カラム名 ○○する ××する 備考 1 id - - 2 name - - 3 ・・ “1” “2” 4 ・・ - システム⽇付 条件 処理

Slide 33

Slide 33 text

要件 設計 設計 実装 Step 3 要求と設計をつなげる

Slide 34

Slide 34 text

33 ⽤語を統⼀する u 業務的な⽤語の意味・使い⽅を定義する • 関係者間で⽤語の意味がずれると、後々⼤きなバグにつながる • 例)携帯電話の契約で「契約開始⽇」とはいつのことか ‒ 契約を申し込んだ⽇?申込が受け付けられた⽇? ‒ (⽉単位で料⾦が発⽣するのであれば)料⾦が発⽣する翌⽉1⽇? ‒ 携帯電話⾃体の「契約開始⽇」とオプションサービスの「契約開始⽇」 では意味が違うケースもある。⽂脈を読んで判断する必要がある。 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3

Slide 35

Slide 35 text

34 WHYをまとめる u 要件や機能だけではなく、その背景(=WHY)を確認する • ⾔われたことだけを実現していても「顧客が本当に欲しかったもの」は ⾒つからない。その背景となる業務を理解しておく必要がある • 背景や設計思想は各設計書に⾔語化して残しておく 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる ××機能 1. ・・・ 2. ・・・・・ 3. ・・・ 機能仕様書 システム ユーザ 〇〇アプリ ××バッチ 機能仕様書 ○○を考慮して、 ××の構成とする ○○という案も検討したが、 ××の理由で断念した

Slide 36

Slide 36 text

要件 設計 設計 実装 Step 4 設計と実装をつなげる

Slide 37

Slide 37 text

36 設計図を⾒直す アプリ u コードの構造をもとに設計図を⾒直していく • アプリケーション内の実装レベル構造と設計書の単位を⼀致させる • 例) 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 プレゼン テーション層 ビジネス ロジック層 データ アクセス層 機能仕様書 IF仕様書 データ更新仕様 【設計】 【実装】

Slide 38

Slide 38 text

37 設計からコード⽣成 u 標準化したフォーマットを使ってコードも⾃動⽣成する • フォーマットの制約に従う必要があるが、品質が安定する • コードと同様に設計ドキュメントも出⼒できることも多い • 例)OpenAPIでのModelオブジェクト⽣成、A5erでのDDL⽣成など 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 Viewer /Editor 設計書ファイル コード⽣成 ツール 開発者 コード

Slide 39

Slide 39 text

38 設計からコード⽣成 u 例)OpenAPI • APIドキュメントの記法をyamlにて標準化 • OpenAPI Generatorにてドキュメント/コード⽣成が可能に 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成

Slide 40

Slide 40 text

要件 設計 設計 実装 Step 5 全てがつながる

Slide 41

Slide 41 text

40 業務⽤語でコード化 u 業務⽤語をそのまま実装コードにする • 例)1週間より⼤きい ‒ 「8⽇以上」と変換しない ‒ 「1週間」という単位や、「より⼤きい」に業務的な意味がある可能性がある • 実装コードとしてはいずれも正しいが、業務的な意味との⼀致しているか を突き詰めることで、要件と実装がつながっていく 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5

Slide 42

Slide 42 text

41 業務⽤語でコード化 u 業務⽤語をそのまま実装コードにする(再) • 例)申込区分が”1” ? ‒ 何を判定しているのかが読み取りにくい • 「新規申込の場合に」だとするとこうなる ‒ コードの可読性が向上する ‒ まずは業務ロジックのメソッド抽出で リファクタリング 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 entity.getOrderType().equals(“1”) entity.isNewOrder()

Slide 43

Slide 43 text

42 責務を考える u どのクラスがどの業務ロジックを持つべきか考える(責務) • 業務をそのまま実装コードに落としていくと、サービスロジックに 業務ロジックが散らばってしまう • クラスが持つ責務を意識して、散らばった業務ロジックを整理する ⇒ 業務の関係性を整理することにつながる(ドメインモデリング) ‒ アプリケーション内でのオブジェクトの構造が 重要になるため、オブジェクト図をベースに 考えると整理しやすい 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える ドメインモデル ○○ドメイン ××ドメイン id name : id name :

Slide 44

Slide 44 text

43 責務を考える u まずはデータと振る舞いをセットで考える • データを保持するオブジェクトから gettterを⽤いてデータを取得している のはコードの不吉な臭い • Entityの責務であるべきロジックを 外に出してしまっている可能性がある 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える entity.getOrderType().equals(“1”) entity.isNewOrder()

Slide 45

Slide 45 text

RDRAのアプローチ

Slide 46

Slide 46 text

45 RDRAのアプローチ u RDRA(Relationship Driven Requirement Analysis) • 軽く柔軟で精度の⾼いモデルベース要件定義⼿法 u 4つのレイヤーで段階的にシステムを分析・設計する • システム価値 • システム外部環境 • システム境界 • システム 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える

Slide 47

Slide 47 text

46 RDRAのアプローチ u 設計図間の関連を重視し、 システム価値~システム をつなげる • 関連を上位⽅向にたどる ことで根拠が明確になる • 影響範囲の特定も容易に 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える

Slide 48

Slide 48 text

DDDのアプローチ

Slide 49

Slide 49 text

48 DDDのアプローチ u DDD(Domain Driven Design)ドメイン駆動設計 • ドメイン(業務領域)エキスパートと開発者が共通⾔語を⽤いて作成した ドメインのモデルをもとに、継続的にソフトウェアを開発する設計⼿法 • 「業務をどのように捉えてモデル化するか」という戦略的設計と 「モデルをどのように実装に落とすか」という戦術的設計がある • DDDに取り組むということは、全員業務を理解する必要があるということ ‒ 業務を知らない実装者は全く⼿が動かなくなる 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える

Slide 50

Slide 50 text

49 DDDのアプローチ u 顧客と共通の⾔語を使い、ドメインモデルを育てる • ドメインエキスパートと開発者で共通の⾔語(=ユビキタス⾔語)を使う • 業務の境界を適切に設定し、区切られた境界ごとにドメインモデリング を⾏う • 業務の変化とともに継続的にモデルを育てる 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える 戦略的設計

Slide 51

Slide 51 text

50 DDDのアプローチ u 実装技術はオブジェクト指向がベース • クラスに適切な責務を持たせ、データと振る舞いを 1つにすることで、コードの可読性・保守性を上げる • Howとして参考にできるものは⾊々あるが、正解はない。 ‒ 値オブジェクト、エンティティ、リポジトリ、アプリケーションサービスなど 番号を ふる Step1 標準化 レイヤー を表現 Step2 関連を 作る ⽤語を 統⼀ Step3 WHYを まとめる 設計図を ⾒直す Step4 設計から コード⽣成 業務⽤語で コード化 Step5 責務を 考える 戦術的設計

Slide 52

Slide 52 text

まとめ

Slide 53

Slide 53 text

52 まとめ 設計は「システムの仕様や構造などを決定する⼯程」 正しく設計すると、 設計を通して、要件と実装がつながっているはず これらの考え⽅をもとに、保守性の⾼いシステム開発を 番号を ふる Step1 設計の質を上げる 標準化 レイヤー を表現 Step2 設計と設計をつなげる 関連を 作る ⽤語を 統⼀ Step3 要求と設計をつなげる WHYを まとめる 設計図を ⾒直す Step4 設計と実装をつなげる 設計から コード⽣成 業務⽤語で コード化 Step5 全てがつながる 責務を 考える

Slide 54

Slide 54 text

その設計つながってますか?