簡単な仕様メモ
- 主な使用言語:PHP, JavaScript
- フレームワーク:FuelPHP
改めて実感したこと
技術選定が2013年、リリースが2016年なのでいろいろ時代遅れな部分は多いのですけど(そもそもFuelPHPそのものの開発が止まってるし)、それにしても独自の開発手法を使ってわかりづらくなってるところが多々あって、設計ってホントに大事だなと感じています。他山の石として。実感したこと。
- フレームワークを活かした機能設計をしないとメンテナンス超大変。
- 規模が大きいサービスでは各層を細分化できる仕組みを取り入れないと、コードが長大になってメンテナンス超大変。
- 最低限でも機能テストを書かないと、機能を追加するときの動作確認が超大変。
それを踏まえて特徴をいくつか挙げると、
- フレームワークとしてFuelPHPを採用しているものの、用意された重要な機能で使っていないものが多い(認証とかORMとか)→ FuelPHPはLaravelなどに比べて機能が少ない代わりに自由度が高くて独自設計をしやすいっていうけどそれにしても
- bootstrap.php で設定したグローバル変数を使い回す素敵仕様があちこちに。グローバル変数なんか今どき使いませんよね(2013年当時ですら使われてないと思う)
- 処理を実装する場所としてロジック層が採用されているが、コードが長大でメンテナンスするのが超大変。1メソッド700行とかザラにある。クエリを組み立てるのに300行とかもある。もう少し細かく分けられたんじゃないかな、、
- 機能テストほぼなし。2017年以降に実装された新機能に関してはちらほら存在する
古いとかいう問題じゃないツッコミどころが満載でなかなかな素敵仕様です。メンテナンス性とは。
フレームワークの機能を使ってない
ログインはAuth パッケージを使わずに独自実装。ログインしたユーザー情報をグローバル変数に格納して使い回すという素敵仕様(他で見たことない)で、セッションとか使わないのと思ったら一応使ってはいる。いるんですけど、セッションから読み込んだのをグローバル変数に格納してて、セッションってそういうことだったっけ。せめてAuthenticationクラスとかでやれば?と思うんだけど全部 bootstrap.php に書かれてて、メンテナンス大変。ORMやクエリビルダも使わずに独自実装。もちろんこれらはフレームワークによって癖があるし、複雑なクエリを書こうとすると結局長大になることも多くて、必ずしも使わなければいけないと言うことではないのだけど、ほとんど同じコードを何十ファイル分書くことを考えるともうちょっとやりようあるんじゃないのと思ってしまいます。せめてモデルはもうちょっと何とかしてほしかった。
独自実装では、1つのモデルにつき「Model」「ModelList」「ModelLoader」「ModelListLoader」と4つのクラスを実装する必要があり、見通しが良くなっている部分も無くはないんですけど、中身も既存のモデルからコピーして編集しなくてはならないので、新しいモデルを追加するのが超大変。開発とメンテナンス、両方のコストから考えて我慢してORM使うべきだったと思うなあ。
さらに「ModelLoader」「ModelListLoader」ではクエリビルダを使わずクエリを自力で組み立ててPDOStatementに投げる独自実装。FuelPHPのクエリビルダは使いにくいし、機能も十分じゃ無いからこうしたい気持ちは痛いぐらいわかる。ただコードが長大になるのでメンテナンスするのが超大変。同じ長くなるのでも、まだクエリビルダの方が視認性が高い気がしました。デフォルトでスパゲッティ必至。
今だとマイクロフレームワークで作れそう
見た感じ自分のそれまでの資産を活かすために独自実装を入れてるようなんですけど、んーーー特別素晴らしい実装というわけではないので、単純に学習コストを惜しんだと言うことかな。機能を独自開発したいという気持ち自体はわからなくはないけど、であればフルスタックなフレームワークは必要ないんですよね。今だと素直にマイクロフレームワーク(Slimとかかな)を採用するんでしょうけど、当時はまだなかったのかな。
こういう技術選定の妥当性を10年後の未来から殴るのはフェアじゃないです。なのでダメ出ししたくはないんですけど、しかし当時でももうちょっとなんとかなったんじゃないかな。
テストは書きましょう
開発体制やサービス規模などの状況もあるのでテストの粒度については議論の余地があってもいいとは思うんですけど、せめてコアな機能についてはテストを書いた方が良いよねと思います。当時も既にテスト駆動とか名前は出てきてたし、概念はあったはず。FuelPHPもPHPUnit動くようになってるし。テストがないとどうなるかというと、何か機能を追加したとき、スクリーンとかログとかデータベースとかを「視認」して対応することになるんですよね。いやもちろんテストを書いたってそれらの確認はするんですが、上手く動かないことの発見が遅くなる。テスト回しながら開発できるとしょうもないミスで巻き戻るって事がなくなるし、マージする前にCircleCIとかで自動化することも出来る。最終的に効率は上がると思うんですよね。リリース後のメンテナンス性も。
テスト書けないぐらい複雑な作りしてんのかなと思って、会員登録だとか注文だとか、ECサイトのコアな部分について試しにテスト書いてみましたけど、テストに必要な部分は長大なコードの中のごくわずかな部分だけで別に大変じゃなかったです。やっぱりポリシーか。
テストって、成功を期待するだけの雑なテストでも良いから何かでもあるとドキュメントの代わりになるんですよね。まあ僕も10年前には「めんどくせえよ」と思ってた側の人間だったので(なぜならチームに自分しかエンジニアがいなくて機能を全て把握してたから)、あんまり偉そうなことは言えませんけど、今みたいに色んなチームで仕事をしているとほんとに大事だなと思います。僕の書くテストはまだまだ未熟ですけどね。精進します。
まとめ
- フレームワークを使うなら極力フレームワークの機能を使いましょう
- グローバル変数は止めましょう
- テストを書きましょう
これを逸脱するような案件は、現代の標準的な開発ではなかなかないとは思いますけど、なくはないからなあ。。次のプロジェクトでも心に刻んで臨みたいと思います。
……なんかね、エンジニアさんが一人で開発したプロダクトを買収しただけど、そのエンジニアさんはジョインしないんで、その開発を引き継いでほしいみたいな話なんですよ。こえー超こえー。あ、でもCTOの人がコードは綺麗だって言ってた気がするんで、それは大丈夫か。逆に勉強させてもらえるかな。こえーけど楽しみでもあります。どんなんかな。