【PHPフレームワークFlow】Flowを半年間触ってみた感想

# 初めに
PHPフレームワークFlowを触り始めて半年がたちました。
Flow関連で書いた記事も気が付くと20前後となり、半年前と比べてかなり知識もついてきたと感じます。
今回は、半年触ってみた感想を記録しておこうと思います。

# FLowとは
Flowとは[flownative](https://www.flownative.com/)社が出しているオープンソースのPHPフレームワークです。

https://flow.neos.io/

**ドメイン駆動設計**（DDD）を中心原理として設計されたフレームワークであり、DDDを満たすための機能を多く提供しています。

## Flowでドメインモデリング
Flowはドメイン駆動設計（DDD）の概念を用いた実装を強く推奨しているフレームワークです。そのため、開発者がDDDを用いた実装がしやすくなるような機能を多数提供しています。

* **ドメインモデルを格納するためのディレクトリ**が最初から用意されている
* **ドメイン知識を表現するためのアノテーション**が用意されている
* ドメインモデルを元に**TBLが自動生成される**
* 自動生成されたTBLへの**CRUDメソッド**が用意されている
* AOPやSignal&Slotなどの**イベント駆動型プログラミング**が実装できる

これらの機能により、以下のような実装が可能になります。
* **記述量の少ないドメインモデルを作成できる**
* **DB, TBLの存在を意識せずに実装できる**
* **単純なCRUDであれば、SQLを書く必要がない**
* **複数集約間の整合性をイベント管理で一元的に実装できる**

これらの機能により実装時間やバグの数を減らし、浮いた時間をドメインエキスパートとの会話やドメインモデリングに費やすことができるというわけですね！

# Flowの好きなところ
ここからは、Flowの個人的に好きなところを書いていこうと思います。

:::note warn
Flowでできることを紹介しますが、Flowでしかできないというわけではありません！
そもそも私自身、Flow以外のPHPFWの経験がありません。「このFWでもできるよ！」など是非教えてください！
:::


## 1. すぐに動かすことができる
前述の特徴と重複しますが、Flowは以下のような特徴があります。
* ドメインモデルからTBLが自動生成される
* 簡単なCRUD操作のメソッドが自動生成される
* デフォルトの場合、Controller名とActionメソッド名からURLが決まる
* 各クラスのひな型を作成するためのコマンドが用意されている

これらの特徴から、**実装開始から動作確認までの時間が全然かかりません**。
サクッと書いてサクッと動作確認できるので、試したいことをすぐに試せるのが個人的に気に入っています。

## 2. 実行前にコンパイルが走る
Flowでは、初回実行時に**コンパイル**と呼ばれる処理が走ります。
コンパイルでは、プロダクトコードをDIやリフレクションなどを解決した形に変換を行います。変換したコードをキャッシュしておき、実行時はこのコードが呼び出されます。

:::note info
Flowの公式ドキュメントでコンパイルと呼ばれていますが、Javaなどのコンパイルとは別物です。
:::


コンパイルによる利点は主に2つあります。
* パフォーマンス向上
* 実行前の簡単なエラーチェック

パフォーマンスについては言わずもがなですね。初回実行時にDIやリフレクションを解決しておけば、その後はそのキャッシュデータを使うことができるので、パフォーマンスが向上します。また、暖機運転のような形で、あらかじめコンパイルをしておくことも可能です。

実行前のエラーチェックについては、おまけ程度の利点です。
存在しないクラスを呼び出している時などは、コンパイル時に潰すことができます。
とはいえ、IDEだったら赤線だしてくれるので、あまり利点を感じたことはありません。


## 3. エラーログが扱いやすい

Flowは、システムログとエラーログがプロジェクト配下のディレクトリに吐き出されます。以下のようなイメージです。

```
Project
    ├ bin/
    ├ Configuration/
    ├ Data/
    |  ├ Logs/
    |  |  └ Exceptions/　←　★エラーログ
    |  |     └ 20240326133322d0ac4f.txt
    |  |     └ 20240326133322fdfc3e.txt
    |  └ System.log　←　★システムログ
    |
    ├ Packages/
    |    ├ Application/
    |    ├ Framework/
    |    └ Libraries/
    ├ Web/
    ├ composer.json
    ├ composer.lock
    ├ flow
    ├ flow.bat

```
エラーログは、エラーが出るたびにファイルが生成され、一つのエラーログに一つのエラーが書いてあるようなイメージです。
これにより、**github-copilotにエラーの原因を聞きやすい**と感じています。
エディタでエラーを開いて、copilot-chatに聞くだけです。

ただ、copilot自体のFlowについて詳しくなく、的外れなアドバイスをされることも多いので、これは参考程度ですね。



# Flowの好きじゃないところ
好きなところを紹介したので、嫌いなところも一点だけ紹介しようと思います。

## DBのデータが分かりづらい
前述の通り、FlowはドメインモデルからTBLを自動生成します。
その際、`persistence_object_identifier`というUUIDのカラムを生成し、それをPKにして管理を行います。
このカラムは全てのTBLに存在し、リレーションを表す際はこのIDがFKになります。
そのため、リレーションの多いTBLのデータを見ると、UUIDだらけでどれがどのデータなのか分かりづらいという特徴があります。

サンプルとして、ECサイトの商品TBLをイメージしたTBLを用意してみました。
以下のような感じで、UUIDだらけでどれがなんなのか分かりづらいですね、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430841/5e4869e6-0326-29d1-8e58-8fe724e8e124.png)

priceがUUIDになっているのは、priceが値オブジェクトとして定義してあるためです。Flowでは、値オブジェクトもTBLとして定義されるため、親TBLから呼び出されるという形になっています。（※設定によっては、親TBLにカラムとして含めることも可能です。詳しくは[こちら](https://qiita.com/nnhkrnk/items/44a15a221356162442c2)。）


# 終わりに
Flowを触り始めて半年がたったのですが、このFW本当に面白いです。
今まで使っていたFWはなんとなくで触っていただけで面白くなかったというのもありますが、Flowは知れば知るほど面白いと感じています。
また半年後に同じ記事を書きたいと思っているので、これからも勉強していきます。

また、この記事でFlowに少しでも興味を持っていただいた方がいましたら、面白いのでぜひ触ってみてください！（以前書いた[環境構築](https://qiita.com/nnhkrnk/items/003a21f31bc8d0546c08)の記事になります）

ここまで読んでいいただきありがとうございました！