※本記事は「RailsからLaravelを眺める」シリーズの第10回です。 Rails出身の私がLaravelを触りながら、Railsと比較して違いを整理していく連載になります。
はじめに
RailsからLaravelに移るとき、多くのRailsエンジニアが最初に「???」となるのが Facade です。Cache::get() や Route::current() のように「静的メソッド呼び出し」に見える書き方は、Ruby文化に慣れた目には「これはグローバル変数的なアンチパターンでは?」と感じられるかもしれません。
Railsでは「依存を明示的に渡す」ことが美徳とされるのに対して、Laravelは「使いやすさと記述のシンプルさ」を優先します。その思想の違いを象徴するのがFacadeです。この記事ではFacadeの正体を整理し、Railsにおける近しい体験を具体例とともに探っていきます。
LaravelにおけるFacade
Facadeは「静的呼び出しに見える依存解決のラッパー」です。
すべてのFacadeクラスは Illuminate\Support\Facades\Facade を継承しており、静的に呼び出されたメソッドは __callStatic でフックされ、最終的にはService Containerから実体が解決されます。
// Laravel
Cache::get('foo');
// 実際には Service Container を経由して解決される
app('cache')->get('foo');
見た目はシンプルな静的呼び出しですが、裏側ではしっかり依存注入が効いている。これがFacadeの核心です。
Railsにある「Facadeっぽい」体験
RailsにはFacadeそのものは存在しませんが、似たような「どこでも呼び出せる便利な窓口」は存在します。
たとえば Rails.cache.read(:foo) は、Laravelの Cache::get('foo') に一番近い書き心地です。内部的にはキャッシュストアが返されており、Facade的に「簡潔な入り口」を提供しています。
また ActiveRecord::Base.connection のようなAPIも同じです。裏では接続プールを管理するオブジェクトが動いていますが、呼び出す側からは「どこでも使える」窓口に見えます。Laravelの DB::table('users') とよく似た体験です。
ビューに登場するHelperもFacade的です。例えば number_to_currency(1234.5) を呼び出せば ¥1,235 という整形済み文字列が返ります。裏側では ActionView::Helpers::NumberHelper が提供している機能ですが、利用者は意識せずに「便利な関数」として扱えます。Laravelの Str::limit() や Arr::pluck() のFacade的呼び出しに近い感覚です。
さらにRailtieも重要な存在です。ActiveRecord::Railtie や ActionController::Railtie はフレームワーク全体にDSLを注入し、config/application.rb から config.active_record.schema_format = :sql のような設定を可能にしています。LaravelにおけるServiceProviderがサービスを登録し、それをFacade経由で呼べるようにする構造とよく似ています。
ActiveSupport::Concernとの違い
ここでよく混同されるのが ActiveSupport::Concern です。RailsのConcernはモジュールをmixinしやすくする仕組みで、included do ... end によって依存関係を整理できます。しかしその目的は「コード共有と再利用性」であり、Facadeのように依存解決の窓口になるわけではありません。
Facadeは「依存を隠して呼び出しを簡潔にする仕組み」、Concernは「モジュールを整理する仕組み」。似ているようで本質的には別物です。
Facadeの利点と課題
Facadeを使う最大のメリットは、書き方がシンプルになり、依存注入を意識せずに済む点です。初心者にとって学習コストが低く、テスト時には Cache::shouldReceive() のようにモック差し替えも可能です。
一方で、静的呼び出しに見えるため依存が隠蔽されやすく、Rails文化に慣れている人には「グローバル変数的でアンチパターン」に見えがちです。Laravelは「依存の透明性」よりも「書きやすさ」を重視しているといえます。
Rails出身者の学び
Railsは「依存を明示的に渡す文化」を重んじ、責務の分離やテスト容易性を優先します。Laravelは「シンプルに書けること」を最優先し、Facadeを通して直感的な呼び出し体験を提供します。
RailsからLaravelを眺めると、Facadeは最初アンチパターンのように見えますが、実際には 「DIを隠した便利なフロントエンド」 です。
グローバル変数ではなく、Service Containerの顔を被った窓口だと理解すると、Laravelの設計思想が一気にクリアになります。
まとめ
LaravelのFacadeは、静的呼び出し風に見せながらも裏で依存注入を行う「依存解決ラッパー」です。RailsにはFacadeそのものは存在しませんが、Rails.cache、ActiveRecord::Base.connection、Helper、RailtieのDSLなどに「Facade的な体験」が散りばめられています。
Concernはしばしば混同されがちですが、目的はまったく異なります。RailsとLaravelでは「明示性を重視するか、書きやすさを重視するか」という文化の違いがFacadeの扱いに現れています。
Rails出身のエンジニアにとって、Facadeを「DIの便利な窓口」と捉えることは、Laravelを理解する大きな一歩になるでしょう。



コメント