Symfony Advent Calendar 2018 21日目の記事です。
昨日は元同僚でもある@kojirock先輩のSymfony4でNelmioApiDocBundleを試してみたでした。
はじめに
@shin1x1さんの独立したコアレイヤパターンは素晴らしいアイデアだと思います。
僕も同じ時期に独立したコアレイヤパターンと同じような事を考えていました。
同じような事を考えている人がいたことが嬉しくて、2017年のPHPカンファレンスで登壇終わったばかりに新原さんを捕まえて一方的に話していました。
しかし「ビジネスロジックをフレームワークやライブラリから分離する」という部分に関しては同じ考えですが、僕が考えていたものとは少し違うものでした。
今回は自分が考えていた構造でサンプルを作ってみたのでそれを紹介したいと思います。
サンプルコードをはこちらになります。
polidog/sf4-business-logic-example
簡単な送金アプリになっています。
動かし方
こんな形で最初にアプリケーションを用意します。(Docker用意してなくてごめんなさい)
|
|
今回使える機能は2つあります。
- 新規で口座を作成する
- 口座から別の口座へ送金する
まずはアカウントを2つ作ります
|
|
送金する場合は以下のコマンドを実行します。
|
|
依存するライブラリについて
基本的なコンセプトとしては「フレームワークやライブラリに依存しない」となりますが、すべてがそうではありません。 状況によってはどうしてもライブラリに依存してしまう事があるでしょう。
今回はDoctrineORMに依存する形にしてあります。
ほぼAnnotationだけなのでそんなに実コードに影響はないかと思います。
ディレクトリ構成
ビジネスロジックに関しては packages/Acmc/Account/srcに配置されるようになっています。
今は一緒のリポジトリで管理していますが、基本的にはビジネスロジックは別のリポジトリでも管理するのもありだと思います。
ControllerやCommandといったものは従来どおりのsrcディレクトリで実装しています。 唯一実装しないのはEnityだけです。Entityはビジネスロジック側にあるので、こちらでは実装しません。
Symfony側の機能を使う場合はInterfaceにする
今回の場合だと外部に依存するものはAccountRepositoryとHistoryRepository なので、2つともInterfaceにしてあります。
設定ファイルに関して
UseCaseクラスに関してDIの設定が必要になります。
またAccountRepository,HistoryRepositoryに関しては実際はどのクラスを使うのかエイリアスを使う必要があります。 今回はservices_account.yamlという設定ファイルを用意しました。
|
|
最後に
なぜビジネスロジックをフレームワークやライブラリから分離するのか?
それはきっと 「ビジネスロジックのコードを修正するときはビジネスロジックが変化するときだけにしたい」 ということです。
フレームワークのバージョンアップやライブラリのバージョンアップでビジネスロジックのコードに修正が入るのはおかしいと思います。
ちなみに同じような構造で実際のプロジェクトでも導入してて、それなりに成果もありました。
ただこの方法も絶対的な正解ではないので、もっと日々良いソフトウェアを作るためにがんばりたいと思います。