誰でもできるサービスレイヤの実装

イントロダクション

CakePHPでは標準でサービスレイヤを提供していません。
しかし、CakePHPフレームワークとしてその基礎部分は十分に提供してると言えます。これはアプリケーション側で実装すべきでしょう。


規模が一定を超えるアプリケーションではサービスレイヤの効能は特筆すべきものがあります。
それは「何をしているか」を端的に表すことができ、開発初期段階において「何が必要か」を明確にし、更にテストを容易にします。
また、トランザクションのサポートもサービス単位で実装することによって、明確に「1サービス1トランザクション」が表現できます。

サービスをモデルとして実装する

上記のサービスモデルは非常に単純化されたサービスモデルの一例です。
これは各モデルのマジックメソッドによる呼び出しを提供します。
saveNewArticleはその例で、使うモデルを一々定義する必要はありません。

コントローラなどからサービスを実行する

サービスレイヤを利用する場合、コントローラ特有のモデルの読み込みはもはや必要ありません。
ただし、IDの自動設定や各種コンポーネントのコントローラのモデルクラスの検出などを利用したいときは、手動でClassRegisrty::init()を用いてサービスクラスを読み込むべきでしょう。
コンポーネント化しても良いですね。

このようにして利用します。
また、シェルでも同じものを利用したい場合があります。例えば、メールからの記事の投稿です。

これを

こうします。簡単ですね。

サービスのテスト

以上までで、サービスレイヤの単純な構築は完了です。ここからは、より高度なサービスの利用を考えます。
まずはテストです。

サービスのテストにはモックが便利です。
これは開発初期段階で、サービスモデルで呼び出すモデルのメソッドやプロパティなどを定義し、後に該当のモデル(ここではArticle)を実装することにより、設計 => 実装をコード単位で表現することが可能になります。

また、モックを利用するには空のArticleモデルを作成する必要があります。

トランザクション処理

ここまできたらトランザクション処理も実装しましょう。
上記の例を拡張したものを考えます。
トランザクションを実装するモデルと、それを中継した呼び出しをすれば良いです。

これでサービスにトランザクションが実装できました。テストは以下のようになるでしょう。

トランザクションの結果までテストすることができましたね!
最後に予想はできるでしょうが、コントローラでの呼び出しはこうなります。

これで非常に叙述的な書き方ができるようになりました。

最後に

アプリケーションが要求するサービスの仕様はもう少し複雑になるかもしれません。
しかし、サービスレイヤのもたらす恩恵は意外に大きいです。
この考えは何もCakePHPに限ったものではないので、習得することをお勧めいたします。