Slide 1

Slide 1 text

https://www.dip-net.co.jp/ 1 バイトルPROソフトウェアアーキテクチャ再設計の取り組み

Slide 2

Slide 2 text

https://www.dip-net.co.jp/ 2 自己紹介 ▼⽒名 ⽶⽥ 宏 dip システム開発1部/バックエンドエンジニア ▼経歴 販売・営業といった職種を転々とした後にプログラマーにジ ョブチェンジをする。 2021年11⽉にdipにジョイン。

Slide 3

Slide 3 text

https://www.dip-net.co.jp/ 3 ▼⾔語 PHP7.4.23 ▼フレームワーク Laravel6 ▼データベース アプリケーション側から直接つなぐことができず、WEBAPIを通して 操作する。 バイトルProの現状のシステム構成

Slide 4

Slide 4 text

https://www.dip-net.co.jp/ 4 ▼課題 ディレクトリやコンポーネントの責務が曖昧。 ▼解決⽅法 ・オニオンアーキテクチャのレイヤー層をディレクトリに当てはめ責 務を整理。 ・戦術的DDDでコンポーネントの責務を明確にする。 現状の課題と解決⽅法

Slide 5

Slide 5 text

https://www.dip-net.co.jp/ 5 現状の主要なディレクトリ構成

Slide 6

Slide 6 text

https://www.dip-net.co.jp/ 6 Domainディレクトリの課題 Component 認証系・ファイル操作・リクエスト処理 ドメインとは関係無い処理が含まれてい る Application ユースケースの⼿続きを⾏う処理 (トランザクションスクリプト) 肥⼤化したメソッドが作られがち Domain リポジトリのインターフェイス・ WEBAPIのDTO コアなドメインコンポーネンツが存在 していそうだが無い

Slide 7

Slide 7 text

https://www.dip-net.co.jp/ 7 Infrastructureディレクトリの課題 Oauth 認証系APIのエンドポイント単位の実装 をしているリポジトリという名前のコン ポーネント Core 主要APIのエンドポイント単位の実装をして いるリポジトリという名前のコンポーネント 双⽅ともリポジトリの実装が集約の単位にな っておらず、リポジトリというコンポーネン ト名と実装内容が⼀致しておりませんでした。 ※参考 https://qiita.com/mikesorae/items/ff8192fb9cf106262dbf (やはりお前たちのRepositoryは間違えている)

Slide 8

Slide 8 text

https://www.dip-net.co.jp/ 8 UseCaseディレクトリの課題 UseCase ユースケースから返すDTO、 Domain/Applicationのインターフェイス Domain/Applicationとユースケースの責 務が重複しているので、実質的に不要な ディレクトリになっている。

Slide 9

Slide 9 text

https://www.dip-net.co.jp/ 9 現状の課題への対応 まずは、オニオンアーキテクチャを採⽤してレイヤー層をディレクト リ名に当てはめることで、ディレクトリ単位での責務を明確にしたい と考えました。

Slide 10

Slide 10 text

https://www.dip-net.co.jp/ 10 オニオンアーキテクチャのご紹介 ▼ドメインモデル層 ビジネスロジックのコアとなるモデルが配置 ▼ドメインサービス層 ビジネスロジック的意味を持つ⼿続き処理が配置 ▼ユースケース層(アプリケーションサービス 層) ユースケースを実現するためにドメンインサービ スやモデルを利⽤して⼿続き的処理を⾏う。

Slide 11

Slide 11 text

https://www.dip-net.co.jp/ 11 オニオンアーキテクチャのご紹介2 ▼インフラストラクチャー層 DBやファイルのアクセスの外部サービスとのや りとりを⾏う処理を配置します。 ▼プレゼンテーション層(UI層) リクエストの処理や表⽰⽤モデルの作成の処理を 配置 ▼テスト ユニットテスト等のテストコードを配置

Slide 12

Slide 12 text

https://www.dip-net.co.jp/ 12 オニオンアーキテクチャを適⽤したディレクトリ構成 ←ドメインモデル層・ドメインサービス層 ←インフラストラクチャー層 ←プレゼンテーション層 ←ユースケース層 ディレクトリがオニオンアーキテクチャの各層に対応して どのディレクトリがどのような責務を持つかが明確になりました。 ※ドメインモデル層とドメインサービス層をディレクトリを分けずに⼀つにしている理由は、 ドメインサービスが対象としているドメインモデルと同じディレクトリに配置したほうが、 関連性が明確になると考え同じにしています。

Slide 13

Slide 13 text

https://www.dip-net.co.jp/ 13 責務を明確にする以外のメリット • 広く知られたパターンを採⽤すれば、新規参画者も把握がしやすい。 • 開発者同⼠でもパターンに存在する共通の語彙を利⽤してコミュニケ ーションができるので便利。(他のアーキテクチャパターンも同様) • 層の依存⽅向がドメイン側に向いているので、 安定しているドメインのロジックが他の層の変更に影響をうけないこ とがうれしい。 (インフラ層やプレゼンテーション層のフレームワークのアップデー ト等の変化の影響から内側の層を守ることができる。)

Slide 14

Slide 14 text

https://www.dip-net.co.jp/ 14 課題への対応 戦術的DDDを適⽤することで、細かなコンポーネントに分類してユー スケース処理を薄くし、責務と実装⽅針を明確にしました。 ※画像引⽤元 翔洋社

Slide 15

Slide 15 text

https://www.dip-net.co.jp/ 15 戦術的DDD(ドメイン駆動設計)とは、ビジネスロジックのモデルを中⼼に 設計するパターン集となります。 主なコンポーネントの種類 • Entity:ビジネスロジックのモデル≒ 集約 • Value Object:ビジネスロジックをもった値 • Domain Service:ビジネスロジック的意味をもつ⼿続き処理 • Application Service:ユースケースを実現する⼿続き処理 • Repository:集約を永続化したり、データから集約を作成する処理 戦術的DDDのご紹介

Slide 16

Slide 16 text

https://www.dip-net.co.jp/ 16 ユースケースより粒度の⼩さいビジネスロジックのコンポーネントが 多くあり、肥⼤化したユースケースの実装をビジネスロジックのコン ポーネントに委譲することで、ユースケースをスリムにできそうです。 また、各コンポーネントの責務や実装の指針も明確に定義されており ます。 DDDコンポーネントのメリット

Slide 17

Slide 17 text

https://www.dip-net.co.jp/ 17 • 広く知られたパターンを採⽤すれば、新規参画者も把握が容易になる。 • 最初にビジネスロジックのモデルを作成するので、リクエストやDBを実 装の起点とした開発に⽐べて⼿続き的処理になりにくい。 その他のメリット

Slide 18

Slide 18 text

https://www.dip-net.co.jp/ 18 LaravelのEloquentを利⽤した開発に⽐べてコード量がかなり多くなる。 戦術的DDDのデメリット

Slide 19

Slide 19 text

https://www.dip-net.co.jp/ 19 コンポーネントの格納先ディレクトリ ←Entity・Value Object・DomainService ←Repository ←Controller・View Model (DDDのコンポーネントではない) ←Application Service ここで紹介されていないコンポーネントも他にたくさんありますが、 各ディレクトリのメインとなるコンポーネントがきまり、 ディレクトリの責務と格納されるコンポーネントの責務を ⼀致させることができました。

Slide 20

Slide 20 text

https://www.dip-net.co.jp/ 20 バイトルPROの⽬標 バイトルPROではこれらのレイヤー層、コンポーネントの指針に沿っ てリファクタリングすることで、新規参画者でも設計の把握が容易で、 実装者毎のブレを少なくした開発を⽬指していきます。

Slide 21

Slide 21 text

https://www.dip-net.co.jp/ 21 Thanks! ご清聴ありがとうございました。