ビジネスロジックを独立させた実装について

December 21, 2018,
tags: symfony


このエントリーをはてなブックマークに追加

Symfony Advent Calendar 2018 21日目の記事です。
昨日は元同僚でもある@kojirock先輩のSymfony4でNelmioApiDocBundleを試してみたでした。

はじめに

@shin1x1さんの独立したコアレイヤパターンは素晴らしいアイデアだと思います。

僕も同じ時期に独立したコアレイヤパターンと同じような事を考えていました。
同じような事を考えている人がいたことが嬉しくて、2017年のPHPカンファレンスで登壇終わったばかりに新原さんを捕まえて一方的に話していました。

しかし「ビジネスロジックをフレームワークやライブラリから分離する」という部分に関しては同じ考えですが、僕が考えていたものとは少し違うものでした。
今回は自分が考えていた構造でサンプルを作ってみたのでそれを紹介したいと思います。

サンプルコードをはこちらになります。
polidog/sf4-business-logic-example

簡単な送金アプリになっています。

動かし方

こんな形で最初にアプリケーションを用意します。(Docker用意してなくてごめんなさい)


$ git clone https://github.com/polidog/sf4-business-logic-example.git
$ composer install
$ bin/console doctrine:create:database
$ bin/console doctrine:migrations:migrate

今回使える機能は2つあります。

  1. 新規で口座を作成する
  2. 口座から別の口座へ送金する

まずはアカウントを2つ作ります

$ bin/console app:create-account
$ bin/console app:create-account

送金する場合は以下のコマンドを実行します。

$ bin/console app:transfer-money

依存するライブラリについて

基本的なコンセプトとしては「フレームワークやライブラリに依存しない」となりますが、すべてがそうではありません。 状況によってはどうしてもライブラリに依存してしまう事があるでしょう。

今回はDoctrineORMに依存する形にしてあります。
ほぼAnnotationだけなのでそんなに実コードに影響はないかと思います。

ディレクトリ構成

ビジネスロジックに関しては packages/Acmc/Account/srcに配置されるようになっています。
今は一緒のリポジトリで管理していますが、基本的にはビジネスロジックは別のリポジトリでも管理するのもありだと思います。

ControllerやCommandといったものは従来どおりのsrcディレクトリで実装しています。 唯一実装しないのはEnityだけです。Entityはビジネスロジック側にあるので、こちらでは実装しません。

Symfony側の機能を使う場合はInterfaceにする

今回の場合だと外部に依存するものはAccountRepositoryHistoryRepository なので、2つともInterfaceにしてあります。

設定ファイルに関して

UseCaseクラスに関してDIの設定が必要になります。

またAccountRepository,HistoryRepositoryに関しては実際はどのクラスを使うのかエイリアスを使う必要があります。 今回はservices_account.yamlという設定ファイルを用意しました。

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true
        autoconfigure: true

    Acme\Account\UseCase\:
        resource: '../packages/Acme/Account/src/UseCase/*'

    Acme\Account\Model\AccountRepository: '@App\Repository\AccountRepository'
    Acme\Account\Model\HistoryRepository: '@App\Repository\HistoryRepository'

最後に

なぜビジネスロジックをフレームワークやライブラリから分離するのか?
それはきっと 「ビジネスロジックのコードを修正するときはビジネスロジックが変化するときだけにしたい」 ということです。
フレームワークのバージョンアップやライブラリのバージョンアップでビジネスロジックのコードに修正が入るのはおかしいと思います。

ちなみに同じような構造で実際のプロジェクトでも導入してて、それなりに成果もありました。
ただこの方法も絶対的な正解ではないので、もっと日々良いソフトウェアを作るためにがんばりたいと思います。

comments powered by Disqus