Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践アプリケーション設計 ②トランザクションスクリプトへの対応

Avatar for Recruit Recruit PRO
August 28, 2025

実践アプリケーション設計 ②トランザクションスクリプトへの対応

2025年度リクルート エンジニアコース新人研修の講義資料です

Avatar for Recruit

Recruit PRO

August 28, 2025
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. (C) Recruit Co.,Ltd. All rights reserved. 2 講師自己紹介 【名前】 藤本

    毅(フジモト タケシ) 【所属】 プロジェクト推進部 【経歴】 IT企業、常駐型開発会社、スタート アップ支援会社、通信キャリア等を 通してB2BからB2Cまで(官公庁シ ステムからチャットサービス、広告、 音楽、エンタメ、旅行、金融、飲食、 HR等)様々なシステムの開発に携 わる
  2. (C) Recruit Co.,Ltd. All rights reserved. 3 当資料の目的 トランザクションスクリプトの構造とその問題点を 踏まえた上で、長期保守のための設計や実装のため

    の参考方法を解説。 最後に実践的なリファクタリング課題を通してコー ドベースで良い設計と実装を理解してもらう。
  3. (C) Recruit Co.,Ltd. All rights reserved. 4 目次 1. トランザクションスクリプトとは

    2. トランザクションスクリプトが選択される理由 3. トランザクションスクリプトのアーキテクチャ 4. トランザクションスクリプトの問題点 5. トランザクションスクリプトが品質悪化しやすい主な原因 6. トランザクションスクリプトの問題への対応 7. R書店のサンプル解説 8. リファクタリングについて 9. リファクタリング課題
  4. (C) Recruit Co.,Ltd. All rights reserved. 5 目次 10. 技術的負債について

    11. トランザクションスクリプトの選択基準 12. 推薦書籍
  5. (C) Recruit Co.,Ltd. All rights reserved. 7 トランザクションスクリプトとは データとロジックを別々に設計する手続き型の設計 手法

    この アプローチでは、まずシステムで扱うデータの 定義や関連性を明確にし、それに基づいてアプリ ケーションの機能や処理を構築していく 伝統的なDB・システム開発の手法として用いられる ことが多い。
  6. (C) Recruit Co.,Ltd. All rights reserved. 8 補足:手続き型とは 「手続き型」とは、プログラムを命令の「手続き(プ ロシージャ)」の流れで記述するスタイルを指す。

    • データ構造と処理を分けて設計し、手続きの順序 で状態を変化させていく考え方。 • トランザクションスクリプトはユースケース (例:「注文を確定」)に対して1つの手続き的な 関数(スクリプト)を書く
  7. (C) Recruit Co.,Ltd. All rights reserved. 9 トランザクションスクリプトにおける モデル •

    データベース設計時のデータモデル(エンティ ティ)をそのままアプリケーション適用。 • データモデルは通常データのみで、アクセサ (Getter / Setter)以外の振る舞い(ビジネスロ ジック)を持たない ※データと振る舞いをセットとするオブジェクト指 向の基本的な思想とも乖離したモデル
  8. (C) Recruit Co.,Ltd. All rights reserved. 11 1. ルールがシンプルで分かりやすい •

    業務処理ごとに関数(スクリプト)を用意する だけで完結する • 設計に複雑な抽象化を必要としないため、開発 の経験値や技術レベルが高くなくても取り組み やすい(そのため人員を確保しやすく、分業も しやすい) • 小規模〜中規模なシンプルなプロジェクト向き
  9. (C) Recruit Co.,Ltd. All rights reserved. 12 2. 既存のフレームワークとの親和性 •

    SpringをはじめとするWebのフレームワークや ライブラリの多くがデータモデルを前提とした 仕様になっている(ORMも基本的に「テーブル 単位」の CRUD を前提としている) • これらの構造は「データベース操作と手続き的 な処理の組み合わせ」に適しており、トランザ クションスクリプトとの相性が良い
  10. (C) Recruit Co.,Ltd. All rights reserved. 14 トランザクションスクリプトの アーキテクチャ 以下のように三層に分かれた構造(三層アーキテクチャ)に

    なっている 引用元:https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFzI0s-ihM14eHcwrcXSket8EZmNXlpQQVqaBE9daX5CKOwVLsP8zuSA9G6XpiGPzhy5Y&usqp=CAU データモデルを用いたアプリケーション(トランザクションスクリプト)の構造
  11. (C) Recruit Co.,Ltd. All rights reserved. 15 三層アーキテクチャの仕組み プレゼンテーション層、アプリケーション層、データア クセス層の3つのレイヤで構成

    三層アーキテクチャ プレゼンテーション層 アプリケーション層 (ビジネスロジック層) データアクセス層 クライアントとの入出力 ユースケースの実現 ドメイン知識の表現 データベースとの入出力 依存関係は 「上の層から下の層」 のみ許可する 引用元:https://booth.pm/ja/items/1835632
  12. (C) Recruit Co.,Ltd. All rights reserved. 17 プレゼンテーション層の役割 • ユーザや外部システムからのリクエスト仕様を定

    義し、リクエストを受け取る • バリデーションや入力形式のチェック • ユースケースを実行するためにアプリケーション 層を呼び出す • レスポンス仕様を定義し、レスポンスを返す
  13. (C) Recruit Co.,Ltd. All rights reserved. 18 プレゼンテーション層の主な構成要素 • コントローラー

    (Controller) • ユーザーからの入力(HTTPリクエストなど)を 受け取り、アプリケーション層に処理を橋渡しす る • アプリケーション層から処理結果を受け取り、レ スポンスを返す • ビュー(View) • HTML等の出力形式に変換してユーザ側に表示す る
  14. (C) Recruit Co.,Ltd. All rights reserved. 20 アプリケーション層の役割 システムの中核を担い、ビジネスロジックを実装す る層。プレゼンテーション層から受け取った情報を

    処理し、必要に応じてデータアクセス層を呼び出し てデータの操作を行う アプリケーション層の主な要素 • サービス(Service) • モデル (Model)
  15. (C) Recruit Co.,Ltd. All rights reserved. 22 サービスとは OASIS(コンピュータと通信に関する標準化団体の 一つ)によるとサービスは「1つ以上の機能にアク

    セスできる仕組みで、規則として定められたイン ターフェースを用いて提供されるもの」と定義され る
  16. (C) Recruit Co.,Ltd. All rights reserved. 23 サービスの登場 「サービス(Service)」という概念は、オリジナ ルのMVC(Model-View-Controller)パターンには

    含まれておらず、後年、特にエンタープライズアプ リケーションの複雑化に伴って登場し、定着した。 2000年代にService Layerパターンとして明確に 提唱された。
  17. (C) Recruit Co.,Ltd. All rights reserved. 24 Service Layerパターン 目的

    アプリケーションロジックを1箇所に集約し、UI層 やドメイン層と疎結合を保つ 特徴 ファサード的にモデルを操作する 引用元: 『エンタープライズアプリケーションアーキテクチャパターン -頑強なシステムを実現するためのレイヤ化アプローチ』
  18. (C) Recruit Co.,Ltd. All rights reserved. 25 サービスの特徴 「状態」を持たない(ステートレス) •

    サービスは 内部に状態を持たず、リクエストに 応じて 一連の処理を調整・仲介する オーケストレーション(指揮・調整)が主な責務 • 振る舞いの本質はモデルや他のモジュールに委ね、 サービスはそれらを組み合わせてユースケースを 実現する。 • 「何をするか」はサービス、「どうするか」はモ デルや他のモジュールが担う
  19. (C) Recruit Co.,Ltd. All rights reserved. 26 トランザクションスクリプト におけるサービス •

    単純なルールに基づいた設計のため、サービスが様々な ビジネスロジックを抱えてしまいがち • データと振る舞いを分けた設計(データをデータクラス、 振る舞いをサービスに持たせる)が構造的に複雑化しや すく、重複コード(部分的重複も)も生まれやすい Service bizFunc1() bizFunc2() Data Model Data Model Data Model bizFunc3()
  20. (C) Recruit Co.,Ltd. All rights reserved. 27 補足:SharedServiceについて トランザクションスクリプトにおいて、サービス間 の共通処理を集めたサービスをShared

    Serviceと 呼ぶことがある(一部の設計パラダイムやフレーム ワークで用いられているServiceの概念)。 • 複数のControllerや個別のServiceクラスで、共通 処理として再利用されるロジックを提供する。 • SharedServiceクラスから個別のServiceクラス のメソッドを呼び出すことは一般には推奨されな い(SharedServiceはあくまで呼び出される側)
  21. (C) Recruit Co.,Ltd. All rights reserved. 29 データアクセス層 データベースやファイルなどのデータの保存先とや り取りを行う層。

    • アプリケーション層(ビジネスロジック層)から のデータの取得・保存要求を受け付け、データ ベースに対してSQLを実行し、結果をアプリケー ション層(ビジネスロジック層)に返す。 • 様々なデータアクセスのパターン(アーキテク チャ)がある
  22. (C) Recruit Co.,Ltd. All rights reserved. 32 ①Table Data Gatewayパターン

    テーブルにアクセスする機能を1つのクラス(もしくは単一のインスタ ンス)に、持たせる(※いわゆるDAOパターン) 例: MyBatis(SQL Mapper)、Doma、LaravelのQuery Builder
  23. (C) Recruit Co.,Ltd. All rights reserved. 33 ②Row Data Gatewayパターン

    テーブルの行に相当するオブジェクトにデータ更新機能(新規/ 変更など)を持たせる 例: .NETのDataRow、Apache Torque
  24. (C) Recruit Co.,Ltd. All rights reserved. 37 長期の保守・運用における問題点 • 開発初期は工数が抑えられるが、長期ス

    パンでは品質が悪化しやすく、長期保守 が難しい • 密結合で巨大な共通クラスが生まれやす く、可読性も落ち、拡張の際にデグレし やすくなる
  25. (C) Recruit Co.,Ltd. All rights reserved. 39 品質悪化の主な原因 1. トランザクションスクリプトが構造的に複雑化

    しやすい 2. ソースコード共通化の失敗(DRY原則の誤った 解釈と適用) 3. プロジェクト内の事情や制約
  26. (C) Recruit Co.,Ltd. All rights reserved. 41 構造的な問題 データと振る舞いを分けて設計していることが構造 的にソースコードの複雑化を助長し、長期での品質

    悪化につながりやすい(オブジェクト指向ではデー タと振る舞いはセットであることが重要 )。 また、状態を持たないサービス(Service)が、様々 なビジネスロジックを雑多に担ってしまう(そのた めロジックも重複しやすい)こともソースコードの 複雑化に繋がりやすい。
  27. (C) Recruit Co.,Ltd. All rights reserved. 43 DRY原則とは DRYは「Don’t Repeat

    Yourself」の略語であり、 Andy HuntとDave Thomasが書籍『達人プログラ マー―システム開発の職人から名匠への道』で提唱 したソフトウェア開発原則 注意点は単に「コードを重複させない」という原則 ではなく、「ソフトウェア開発全体において情報を 重複させない(同じ意味や機能を持つ情報を複数の 場所に重複して置くことをなるべく避けるべき)」 という原則
  28. (C) Recruit Co.,Ltd. All rights reserved. 44 DRY原則の誤用(共通化の失敗) DRY原則の誤用で共通化を行うと、コンポーネント 間の密結合を招きやすく、結果としてソースコード

    の複雑化につながる。 そのため、影響範囲や役割を整理しながら、 高凝集・疎結合を実現するように責務を限定して共 通化を設計することが重要。
  29. (C) Recruit Co.,Ltd. All rights reserved. 45 補足:凝集度と結合度 凝集度・結合度とは、ソフトウェアの品質を表す指標 (メト

    リクス)で、高凝集・低結合にすると、一般に以下のように ソフトウェア特性が改善される。 • Understandability(理解容易性): コードを読んで理解 しやすくなる • Flexibility(拡張性): コードを修正、拡張しやすくなる • Reliability(信頼性): 修正時にバグを埋め込みにくくな る • Reusability(再利用性): 同じコードを別の場所で再利用 しやすくなる • Testability(テスト容易性): テストを実施しやすくなる
  30. (C) Recruit Co.,Ltd. All rights reserved. 47 大規模開発の現場における制約 開発者の知識やスキルが一定でない(経験値や技術 力の異なる開発者が集まり、常に技術力が高い人を

    確保できるわけではない)ため、全員が理解し、実 践できるルールや手法を用いる必要がある。 また、定期的な人員の入れ替わりも考慮する必要が ある。
  31. (C) Recruit Co.,Ltd. All rights reserved. 48 共通ルールの欠如や未遵守 • ルールがシンプルなため、開発者個人の経験や暗

    黙知に依存してしまう • ルールを敷いてもチーム間や開発者間でも認識が 違ったり、遵守の度合いが異なることも少なくな い
  32. (C) Recruit Co.,Ltd. All rights reserved. 50 問題への対応方法 • 概念や目的を意識した共通化

    • 高凝集・疎結合を意識した設計・実装 • ポイントを絞ったプロジェクト内のルール設定
  33. (C) Recruit Co.,Ltd. All rights reserved. 52 ソースコード共通化のポイント 「カタチが似ているから」といって安易に共通化し ないこと。

    見た目や構造が似ていても、背後にある概念や目的 が異なる場合は共通化すべきではない。
  34. (C) Recruit Co.,Ltd. All rights reserved. 54 主な設計・実装のポイント • 命名

    • 不変性 • アクセサの制限 • 早期リターン • 複雑な生成処理の隠蔽 • 可視性の制御(アクセス修飾子) • 単一責任の原則(SOLID原則) • 驚き最小の原則 • エラーは戻り値で返さず、例外をスローする • 継承より委譲 • 値オブジェクトの活用 • インターフェースの活用(Strategyパターン) • DTOの安易な多用を避ける • 本番で車輪の再発明をしない
  35. (C) Recruit Co.,Ltd. All rights reserved. 58 1. 名前は「概念」を表す •

    名前(クラス名、メソッド名、フィールド名) は、ソフトウェアにおける「意味づけ」の出発点 • 適切な名前をつけることで、「何をするものか」 「何を表しているのか」がコードの構造として自 然に現れやすくなる ※トランザクションスクリプトでは軽視されやすい
  36. (C) Recruit Co.,Ltd. All rights reserved. 59 2. 名前が「構造」を導く •

    たとえば、Order, Customer, Inventory と いった名前を与えることで、それぞれが何の責務 を持つのか、どんな関係があるのかを開発者が自 然に考え始める • 名前を変えるだけで、責務や設計方針すら変わる こともある (例えばUserServiceから UserRegistrationServiceに名前を変更するだ けで責務が変わる)。
  37. (C) Recruit Co.,Ltd. All rights reserved. 60 補足:言葉の意味について 言葉の意味は絶対的なものではない •

    記憶の集積から生成されるイメージ • 文脈に依存(様々な前提や条件) • 捉え方(個人の主観) PRJやチーム内で認識が共有できていることが大事
  38. (C) Recruit Co.,Ltd. All rights reserved. 61 一意でシンプルな名称 メンタルマッピングを避けるため、一意でシンプル な名称が望ましい。

    また、略称はなるべく避ける。 略称を使用する場合は一般的に使用されているもの を用いること 例: BankならBk..etc
  39. (C) Recruit Co.,Ltd. All rights reserved. 65 補足:副作用について 関数(メソッド)が引数を受け取り、戻り値を返す 以外に、外部の状態(変数等)を変更すること

    • 主作用:関数(メソッド)が引数を受け取り、値 を返すこと • 副作用:主作用以外に状態変更すること
  40. (C) Recruit Co.,Ltd. All rights reserved. 66 不変性の例:メソッド引数 引数にfinalを付与して不変にする 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=

    se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  41. (C) Recruit Co.,Ltd. All rights reserved. 74 早期returnとは 条件を満たしていない場合に、ただちにreturnで抜 けてしまう、という手法。早期returnすることで分

    岐の複雑化を軽減し、可読性を上げる。 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  42. (C) Recruit Co.,Ltd. All rights reserved. 76 ファクトリの活用 生成ロジックが複雑化し、増えすぎたらファクトリ クラスを検討すること

    引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  43. (C) Recruit Co.,Ltd. All rights reserved. 77 ファクトリの利点 • 引数が大量にある複雑な生成ロジックをカプセル

    化できる • ファクトリは名前を付けることができるため、オ ブジェクトによって複数の生成パタン(コンスト ラクタ)が生じる場合等は、ファクトリを活用す ることで整理するのが望ましい
  44. (C) Recruit Co.,Ltd. All rights reserved. 79 アクセス修飾子を用いた可視性の制御 publicやprivate、アクセス修飾子なし(package private)、などアクセス修飾子を付与することで、

    クラスやメソッドの可視性を制御できる。 意味もなくpublicにすると可読性が下がる他、色ん な箇所から呼び出すことができるようになると、影 響範囲が広くなり、密結合や無秩序や拡張を生みや すくなる。その結果、クラスや関数の責務や用途を 限定しづらくなり、設計が崩れやすくなる。
  45. (C) Recruit Co.,Ltd. All rights reserved. 80 Javaのアクセス修飾子 但し使用するフレームワークやライブラリの仕様上 付ける必要があるケースもある

    (今回のJPAやThymeleaf等) 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  46. (C) Recruit Co.,Ltd. All rights reserved. 82 SOLID原則 • S

    (Single Responsibility):単一責任の原則 • O (Open-Closed):オープン・クローズドの原則 • L (Liskov Substitution):リスコフの置換原則 • I (Interface Segregation):インターフェイス分離の原則 • D (Dependency Inversion):依存性逆転の原則
  47. (C) Recruit Co.,Ltd. All rights reserved. 83 S (Single Responsibility)

    単一責任の原則 クラスは、単一の責任を持つべきだ。 引用元:https://qiita-user- contents.imgix.net/https%3A%2F%2Fmiro.medium.com%2Fmax%2F4800%2F1%2AP3oONz9Da3Tc1w97fMV73Q.p ng?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=9bde1e1199558885fbde9ada01aa8bfb
  48. (C) Recruit Co.,Ltd. All rights reserved. 84 神クラスの排除 トランザクションスクリプトでは、たくさんの役割 を担った結果、「どのようなクラスなのか」輪郭さ

    えも曖昧になった「神クラス」が生まれることも少 なくない。 そのため、巨大なクラスや関数を作らないためにク ラスや関数の責務や適用スコープを絞ったり限定す るために定期的なリファクタリング等を行うのが望 ましい。
  49. (C) Recruit Co.,Ltd. All rights reserved. 85 O (Open-Closed) オープン・クローズドの原則

    クラスは、拡張にはオープンで、変更にはクローズドであるべ き(あるクラスを修正するときに、他のクラスに影響が出ない ような設計であること) 引用元:https://qiita-user- contents.imgix.net/https%3A%2F%2Fmiro.medium.com%2Fmax%2F5200%2F1%2AyKk2XKJaCLNlDxQMx1r55Q.png?i xlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=6aa3d527b3a33083281ec215905ee626
  50. (C) Recruit Co.,Ltd. All rights reserved. 86 L (Liskov Substitution)

    リスコフの置換原則 親オブジェクトを子オブジェクトに置き換えても、その プログラムの特性は何も変わらない(オブジェクトは スーパータイプのオブジェクトの仕様に従わなければな らない) 引用元:https://qiita-user- contents.imgix.net/https%3A%2F%2Fmiro.medium.com%2Fmax%2F5200%2F1%2AyKk2XKJaCLNlDxQMx1r55Q.png?ixlib=rb- 4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=6aa3d527b3a33083281ec215905ee626
  51. (C) Recruit Co.,Ltd. All rights reserved. 87 I (Interface Segregation)

    インターフェイス分離の原則 そのクラスに使用しない振る舞いと外部へのインター フェースは持たせない(例えばSmartPhoneインター フェースの「テキストを送る」振る舞いを別のインター フェースに分離して、PocketBellクラスに実装させる等) 引用元:https://qiita-user- contents.imgix.net/https%3A%2F%2Fmiro.medium.com%2Fmax%2F5200%2F1%2A2hmyR9L43Vm64MYxj4Y89w.png?ixlib=rb- 4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=bde111d6486182c7c599b4426bbb2d16
  52. (C) Recruit Co.,Ltd. All rights reserved. 88 D (Dependency Inversion)

    依存性逆転の原則 呼び出し元(上位モジュール)は呼び出し先(下位モジュー ル)に直接依存しない。抽象化で繋がる(下位モジュールは 多相性により取り替え可能) 引用元:https://qiita-user- contents.imgix.net/https%3A%2F%2Fmiro.medium.com%2Fmax%2F5200%2F1%2AQk8tDmjQlyvwKxNTfXIo0Q.png?ixlib=rb- 4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=aac256989fe4f02e3d12a5f2c9b4ea39
  53. (C) Recruit Co.,Ltd. All rights reserved. 89 DIP(依存性逆転の原則)の補足 DIPは依存関係の方向を具体的な実装から抽象的な 契約へと—変えることで、柔軟で疎結合なシステム

    を実現する 引用元:https://blog.openreplay.com/ja/%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%81%AE%E5%8E%9F%E5%89%87- %E8%AA%AC%E6%98%8E/ DIPの例
  54. (C) Recruit Co.,Ltd. All rights reserved. 95 エラーは戻り値で返すべきではない エラーを「戻り値」で返すと本来の値の他にエラーとしての意 味を持たせるため、ダブルミーニングになる

    引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  55. (C) Recruit Co.,Ltd. All rights reserved. 97 補足:例外は「副作用」の一つ 例外は副作用に当たるが、明確なエラー伝播と意図 の分離(設計の明瞭性と保守性)を優先し、エラー

    は戻り値では返さず、例外をスローすること。 但し、処理効率が極めて重要なシーンでは、むしろ 副作用を抑えた「戻り値によるエラー処理」が選ば れる場合もある。
  56. (C) Recruit Co.,Ltd. All rights reserved. 99 継承は慎重に用いるべき理由 共通化目的等での安易な継承は危険 •

    不必要な依存関係・密結合を生みやすい 影響範囲が広くなる • 上位クラスの変更が下位に波及し、保守性を下げ る 本質がズレることも • 「is-a関係」が成り立たない継承は、設計破綻の 温床になりやすい
  57. (C) Recruit Co.,Ltd. All rights reserved. 100 継承より委譲 利用したいクラスをスーパークラスとして継承するの ではなく、インスタンス変数として持ち、呼び出す

    引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  58. (C) Recruit Co.,Ltd. All rights reserved. 103 値オブジェクトとは 値オブジェクトとは、文字列型やプリミティブ型の 代わりに、意味のある専用クラスとして値を表現す

    るための設計パターン。 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  59. (C) Recruit Co.,Ltd. All rights reserved. 104 Value Object(値オブジェクト) パターンとは

    数値・文字列・日付などのプリミティブな値を、意 味を持つオブジェクトでラップする設計手法。 代表的な性質は以下3つ • 不変である • 生成後に状態が変更されない(副作用の排除) • 等価性によって比較される • 同じ値を持つ値オブジェクトは等価とみなす • 交換が可能である
  60. (C) Recruit Co.,Ltd. All rights reserved. 105 値オブジェクトの利点 • ラップする値の不変性を担保できる(値が書き換わ

    らないため、スレッドセーフであるともいえる) • 型で定義できるため、意味を伝えやすく(可読 性)、関数の戻り値等にも有効(プリミティブ型で はわかりにくい) • 値に関するビジネスロジックを集約して、高凝集を 実現し、整理しやすい(同じような関数が複数存在 する等を回避できる)
  61. (C) Recruit Co.,Ltd. All rights reserved. 106 値オブジェクトの基準 意味のあるもの、不変性を必要とするものを値オブ ジェクト化する(必ずしも全てを値オブジェクトに

    すべきというわけではない)。 ここでは以下の基準を設ける • IDや日付等の内部で扱う情報には値オブジェクト を適用しない • 金額に関するものには値オブジェクトを用いる • パスワードは値オブジェクトとする
  62. (C) Recruit Co.,Ltd. All rights reserved. 107 注意:J2EEコミュニティにおける “Value Object”とは別概念

    「バリューオブジェクト」「VO」という名称はデー タ変換オブジェクトの意味で使われることも多いので 混同しないように注意
  63. (C) Recruit Co.,Ltd. All rights reserved. 109 膨れ上がるswitch文への対処 膨れ上がるswitch文に対してインターフェース (Strategyパターン)を応用して対処できる

    引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  64. (C) Recruit Co.,Ltd. All rights reserved. 110 Strategyパターンとは 同じインターフェイスを実装する交換可能な「戦 略」をいくつか定義して、プログラム実行時に選

    択・切り替えをできるようにするパターン。 引用元: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIlecN5TguwKAhYH-MNFJjxI4CV2yYAgqmsQ&s
  65. (C) Recruit Co.,Ltd. All rights reserved. 111 インターフェース活用の利点 (多態性の活用) 分岐の複雑さを抑える(可読性向上)

    複雑な if や switch による分岐処理を、インターフェー スの多態性で置き換えることで、コードがシンプルかつ 拡張しやすくなる。結合度も抑えられる 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  66. (C) Recruit Co.,Ltd. All rights reserved. 113 DTO(Data Transfer Object)とは

    システム内部またはシステム間でデータをやり取り(転送)す るために使われる、データのみを持つオブジェクト 引用元:https://www.amazon.co.jp/-/en/仙塲-大也-ebook/dp/B0DPW38VVV/ref=tmm_kin_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.ICYS5d0mLx2TFsj1Tq0iRXpTC60iNtfulSGtwXIphY5QeGZ- _bBqBeX8z0Foxr0_Yz0XDm15cbJHZPd0bGNPL7AHobFMid0OvCQwLF9PkCT6gV-Z6DiH0eXZ53X9XzcF.CJ2gWSEaFVHGVgpdgMv8uPgud8RHUOJoXo_bI7GH8G0&qid=1751988304&sr=1-2-spons
  67. (C) Recruit Co.,Ltd. All rights reserved. 115 DTOの利点 • カプセル化

    • モデルからDTOにデータを移すことで、モデルの 不要なフィールドや振る舞いを外部から隠蔽する • 通信の効率化 • 必要な情報だけを抽出して送信
  68. (C) Recruit Co.,Ltd. All rights reserved. 117 凝集度の低下 • データと振る舞いのううち、振る舞いを持たない

    ため、モジュールの凝集度を低める • 本来のオブジェクト指向の原則(データと振る舞 いをセットで持つ)にも合致しない
  69. (C) Recruit Co.,Ltd. All rights reserved. 120 DTO使用の際の注意 • 頻繁な入れ替えはDTO間の受け渡しは控える

    • 本来値更新の責務はないため、フィールドはfinal で不変性を保つ • 似たDTOはパッケージや生成箇所をまとめ、高凝 集を保つ
  70. (C) Recruit Co.,Ltd. All rights reserved. 122 DBとのマッピングにDTOを用いない理由 • 複雑な仕様にも対応できるようにするため

    • DTOは基本フィールドが不変(Immutable)でビ ジネスロジックを持たないため制限が多い • DBに直接マッピングされるオブジェクトとそれ 以外のデータの入れ物としてのDTOを区別しやす くするため • 似た意味合いのDTOが複数あると、どちらを使う か迷ったり、データモデルとの棲み分けの区別が つきにくくなる
  71. (C) Recruit Co.,Ltd. All rights reserved. 124 本番(プロダクションコード)で 「車輪の再発明」は御法度 「車輪の再発明(reinventing

    the wheel)」と は、すでに世の中に広く使われていて、よく検証さ れている解決策・ツール・ライブラリを無視して、 自分で一から同じようなものを作ってしまうこと。 再利用性が低かったり、品質が保証されない等のデ メリットが多い
  72. (C) Recruit Co.,Ltd. All rights reserved. 126 大規模プロジェクトでの ルール策定のポイント •

    人が入れ替わったり、レベルが保てなくてもある 程度回るようにできるだけシンプルであること (誰が見ても、人が入れ替わっても理解できるこ と) • 100点を目指して、色々盛り込むよりも条件を絞 ること(例えばこの資料のように)
  73. (C) Recruit Co.,Ltd. All rights reserved. 132 今回のアクターとユースケース 今回のシステムのアクター •

    顧客 サイト管理者 • 配送センター管理者 • 配送会社担当者
  74. (C) Recruit Co.,Ltd. All rights reserved. 135 今回のアプリケーションの構成と 使用フレームワーク •

    SpringBootを用いたモノリシック構成(三層アーキテ クチャ) • データアクセスはHibernate(JPA)+ Repositoryパ ターン
  75. (C) Recruit Co.,Ltd. All rights reserved. 138 補足:JavaにおけるHelperクラス Helperクラスは、他のクラスの役割を補完・支援す るための処理ロジックや操作関数を提供するクラ

    ス。 通常はビジネスロジックに直接関与しない補助的な 処理(たとえば、文字列操作、モデルの変換、補 助)等を担う。
  76. (C) Recruit Co.,Ltd. All rights reserved. 141 商品詳細ページでの データ参照方法について 例えば、書籍の詳細ページでは、リクエストに含ま

    れる商品番号を基に書籍データを取得する。 その場合、書籍(データ)モデルは商品番号を持た ないため、スーパータイプの商品をJOINして参照す ることが可能 書籍 (books) 商品番号 商品番号 商品 (products) HTTP(S)リクエスト 書籍 モデル Join
  77. (C) Recruit Co.,Ltd. All rights reserved. 143 ドメイン駆動設計(DDD)の実装との比較 • サービス層がロジックの吹き溜まりになりがち

    (重複コードも生まれやすい) • Helper や Util に逃したロジックが再利用性や整 合性を損なう • ビジネスルールの全体像がコード上で追いづらい
  78. (C) Recruit Co.,Ltd. All rights reserved. 145 リファクタリングとは リファクタリングとは、ソフトウェアの外部的振る 舞いを保ちつつ、理解や修正が簡単になるように、

    内部構造を改善することで、アジャイル開発のみな らず、ウォーターフォール開発においても、ソフト ウェアのコード品質を上げていく上では欠かせない 取り組み。
  79. (C) Recruit Co.,Ltd. All rights reserved. 149 専用リポジトリのDL 以下URLからリポジトリファイルをDLしてください 本資料の「高凝集・疎結合を実現するための設計・

    実装のポイント」等を見ながら「まず何が問題なの か」仮説を立てて、取り組むと効果的です。 URL: https://ghe.misosiru.io/takeshi- fujimoto/rbooks-jpa-exercise
  80. (C) Recruit Co.,Ltd. All rights reserved. 151 技術的負債とリファクタリング リファクタリングを怠ると、技術的負債が蓄積され、 スパゲッティのようなプログラムになって

    いき、最 終的には修正などを手を入れることができなくなる。 このような状況に陥ると、プロ ジェクトが回らなく なり、失敗につながる。 但し、技術的負債をなるべく作らないことが絶対正 義とは限らない。
  81. (C) Recruit Co.,Ltd. All rights reserved. 152 リクルートの社内PRJにおける リファクタリング 当社では常にエンジニアリングに対する事業価値を

    求められ(『事業価値とエンジニアリング』を参 照)、 リファクタリングに対しても同様の投資効果 を求められる。 また、事情によりテストコードを作らない(テストは 手動で実施する)プロジェクトもあり、自動化したテ ストがないため、リファクタリングを頻繁に実施し ずらいプロジェクトも存在する。
  82. (C) Recruit Co.,Ltd. All rights reserved. 153 技術的"負債"の元々の捉え方 「技術的負債」の提唱者のウォード・カニンガムによ ると、本来の意味での技術的負債は金融の

    借り入れと 同様に(リファクタリング)で返済するもの。借入をすれ ば物事をより早く前に進めることができる(つまり早く リリースできる)メリットもあるのでバランスが大事。 引用元:https://www.youtube.com/watch?v=pqeJFYwnkjE&t=110s
  83. (C) Recruit Co.,Ltd. All rights reserved. 154 “負債のメタファー”で重要なこと 〝負債のメタファーで大事なのは返済してメタ ファーを味方につける力であり、それは問題を理

    解 するに従ってリファクタリングしていけるような、 十分にきれいなコードを書いているかどう かで決ま る〝 引用元:【翻訳】技術的負債という概念の生みの親 Ward Cunningham 自身による説明 - t-wadaのブログ (hatenablog.jp) 但し「後できれいに書き直すつもりなら雑なコード を書いてもいい」という話ではないので注意
  84. (C) Recruit Co.,Ltd. All rights reserved. 156 トランザクションスクリプトをいつ使うべきか • トランザクションスクリプトが向いているのは、

    業務ロジックが手続き的なデータ操作だけ、とい う単純な問題領域 • 小さなプロジェクト(予算も限られる)でスピー ドが求められる場合や、初期開発から変更の少な いプロジェクト等もトランザクションスクリプト が適しているといえる
  85. (C) Recruit Co.,Ltd. All rights reserved. 157 リクルートではトランザクションスクリプト を選択するプロジェクトが少なくない 1.

    R社内ではウォーターフォール開発が多く、特に初 期開発ではどんどん仕様が変更になりやすい 2. スピードを重視することが多いため、例えばDBと アプリケーションが別々に検討(なるべく連携はと りつつも)が進むことも少なくない 3. その場合は、データと振る舞いを分ける手続型のアプ ローチ(トランザクションスクリプト)を選択すること が少なくない
  86. (C) Recruit Co.,Ltd. All rights reserved. 159 『改訂新版 良いコード/悪いコード で学ぶ設計入門』

    リクルートのプロダクト開発におけるソースコード共通化等の課題の ヒントになるような項目が並び、著者の探求した知見が詰まっている 引用元: https://m.media-amazon.com/images/I/81jRrINa7jL._SL1500_.jpg
  87. (C) Recruit Co.,Ltd. All rights reserved. 160 『プリンシプル オブ プログラミング』

    3年目までに身につけたい 一生役立つ101の原理原則 コードベースの内容ではないものの、コーディ ングや設計に必要な考え方がまとめられた良書 引用元:https://m.media-amazon.com/images/I/61IQxm626YL._SL1500_.jpg
  88. (C) Recruit Co.,Ltd. All rights reserved. 161 『現場で役立つシステム設計の原則』 従来のドメイン駆動設計を咀嚼する形で、ドメインモデルを用 いた設計について、Webシステムの基礎から触れている良書。

    エリック・エヴァンスのドメイン駆動設計とやや異なる点があ るので注意 引用元:https://m.media-amazon.com/images/I/816kPT38qiL._SL1500_.jpg