UUUM攻殻機動隊(エンジニアブログ)スマートフォン用の表示で見るUUUM攻殻機動隊(エンジニアブログ)UUUMのエンジニアによる技術ブログです2017-04-26Railsアプリ開発中に思い出す、StrategyとRackミドルウェアRailsこんにちは、エンジニアのナカハシです。最近は、しばらくRailsでのWebアプリ開発に勤しんでいる毎日です。開発中にStrategyとRackミドルウェアを復習したので、軽くまとめてみました。Strategyってなんだっけ?今私が開発に参加しているファンクラブサイトは、複数種類のファンクラブサイトを1つのアカウントでログインできるようにしています。各ファンクラブサイトのアクセス許可は、共通アカウント基盤に対してOAuth2で行うようにしています。Railsでのこの手のログイン認証を得る場合、対応するomniauth-xxxというgem(omniauth-twitterとかomniauth-facebookなど)を利用すると手軽に実現できるわけですが、それらのライブラリは以下のようなモジュール構造(名前空間)を持っています。いう名前で実装しています。いう名前が登場します。GOFのデザインパターンにStrategyという名前の手法があるのですが、私は名前だけ覚えていて中身を忘れていました。今一度、ここを復習してみます。GOFのデザインパターンにおけるStrategyGOFのStrategyパターンは、ロジックを提供するオブジェクトを使う側と分離し、交換可能にするという設計手法です。)を実行する構成を考えてみましょう。クラスのインスタンスが回復役の場合は「ケアル!」と唱えることを実現できるようにします。Rubyで実装するとすれば、以下のようなクラス構成になるでしょう。実行されるロジックを簡単に差し替えることができます。Injectionなどとほとんど同じ構造ですし、オブジェクト指向プログラミングをしている場合は、無意識のうちにどんどん使うでしょう。いう名前空間に属していることもあるので、私はStrategyパターンを利用した設計と考えました。omnioauth-xxxのインスタンスを保持してロジックを実行するモジュールは、当然それが何なのかについて、大まかに知っているでしょう。ロジックを実行しているモジュールを調べてみました。すると、以下のクラスから実行されているということがわかりました。このBulletは、N+1問題を検出してくれるためのgemです。Bulletは全く関係ありません。これは、GOFのStrategyパターンによる実装といっていいのでしょうか?GOFのStrategyパターンに関して言えば、重要なエッセンスは「ロジックを独立したインスタンスで提供し、交換可能にする」という部分でしょう。OmniAuthのStrategyは、GOFのStrategyパターンと全く関係がない、ということはないのだろうと思います。それは、両者がRackミドルウェアだからです。Railsアプリは、Rackインターフェイスの要件を満たしています*1。従ってRailsアプリは、Rackミドルウェアの集合体と見ることもできます。以下のコマンドを打てば、現状のアプリを構成しているRackミドルウェアのスタックを見ることができます。OmniAuth::Strategies::UuumidRailsアプリは、リクエストを受け付けると、このRackミドルウェアスタックを順に実行します。Rackミドルウェアスタック的にはBulletのすぐ下に配置されていました。これなら、OmniAuthのStrategyがBulletという全く関係のないモジュールから呼び出されていることも理解しやすいです。GOFのStrategyパターンを頭に入れると、「これがStrategyなのか?」と少しわからなくなりますが、疎結合という意味ではむしろ好ましい形の実装といえるのかもしれません。Design(デザインブログ)はてなブログをはじめよう!uuum-staffさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。