There are a lot of online resources about how to use a Guice Provider to bind to a generic class, such as wiki entries like this and SOF questions like this. However, I am having trouble finding a
seen from Russia
seen from China
seen from China
seen from United States
seen from United States
seen from United States
seen from China

seen from United Arab Emirates
seen from United States
seen from United Kingdom

seen from Malaysia
seen from Pakistan
seen from United States
seen from Libya

seen from Brazil

seen from United Kingdom
seen from Australia

seen from United States
seen from Malaysia
seen from China
There are a lot of online resources about how to use a Guice Provider to bind to a generic class, such as wiki entries like this and SOF questions like this. However, I am having trouble finding a
This question is a continuation of Using guice for a framework with injected classes, proper way to initialize?, which I've tried to implement, and also tried other ways to get around the issue, but
I have a concern regarding Guice and whether or not its singletons will obey thread confinement that I may try to set up: public class CacheModule extends AbstractModule { @Override protec...
Apache Polygene™ is a community based effort exploring Composite Oriented Programming for domain centric application development. This includes evolved concepts from Aspect Oriented Programming, Dependency Injection and Domain Driven Design. Composite Oriented Programming allows developers to work with 'fragments', smaller than classes, and 'compose' fragments into larger 'composites' which acts like the regular objects. Apache Polygene™ also tackles the enforcement of application composition, i.e. composites are declared in modules, modules are contained in layers and access between layers are controlled/enforced.
DIとサービスロケータの違い
DIとサービスロケータは、いずれもオブジェクトの構築と依存の解決という仕事を切り出すためのパターンです。ところで、この2つのパターンの違いを明確に説明できるでしょうか?
Pimpleでシンプルに正しくDIを理解する のコードは以下のようになっていました。
<?php require_once '../vendor/pimple/pimple/lib/Pimple.php'; // インフラ interface MailerInterface { public function send($body); } class SendmailMailer implements MailerInterface { public function send($body) { } } // ドメイン class NewsletterTransfer { protected $mailer; public function __construct(\MailerInterface $mailer) { $this->mailer = $mailer; } public function send($newsletter) { $this->mailer->send($newsletter); } } $container = new \Pimple(); // オブジェクトコンストラクションのコンフィギュレーション $container['infrastructure.mailer'] = function($container) { $mailer = new \SendmailMailer(); return $mailer; }; $container['domain.transfer.newsletter'] = function($container) { $newsletterTransfer = new \NewsletterTransfer($container['infrastructure.mailer']); return $newsletterTransfer; }; // オブジェクトの利用 $newsletterTransfer = $container['domain.transfer.newsletter']; $newsletterTransfer->send('ニュースレター本文');
DIの仕組みを解説するためのこのコードには、実は、DIパターンとサービスロケータパターンとが混在しています。このコードから、オブジェクトごとのまとまりを意識してパーツを取り出すと、次の3つになります(利用側から順に並べています)。
<?php // オブジェクトの利用 $newsletterTransfer = $container['domain.transfer.newsletter']; $newsletterTransfer->send('ニュースレター本文');
<?php // ドメイン class NewsletterTransfer { protected $mailer; public function __construct(\MailerInterface $mailer) { $this->mailer = $mailer; } public function send($newsletter) { $this->mailer->send($newsletter); } }
<?php // インフラ class SendmailMailer implements MailerInterface { public function send($body) { } }
図にすると、次のようになります。
どこがDIで、どこかサービスロケータなのでしょうか? また、この3つのオブジェクトの仲介役として機能するコンテナは、DIコンテナなのでしょうか?サービスロケータ(の対象コンテナ)なのでしょうか?
オブジェクトから見たコンテナの位置づけ
DIなのかサービスロケータなのか、この2つの違いを明確にするには、オブジェクトがコンテナに何を求めているのかを理解しなくてはなりません。
必要なオブジェクトをコンテナから取り出す(能動的)
上のコードの入口部分にあたる「オブジェクトA」をAさんが開発しているとしましょう。Aさんの視点だけをピックアップしたのが次の図です。
オブジェクトBやオブジェクトCの開発はAさんの担当ではありません。オブジェクトBがどのように構築されるのかは、コンテナに定義されているため、Aさんは単にコンテナからオブジェクトAを取り出して、使うだけです。
オブジェクトAからは、コンテナを直接参照し、名前をキーにして使いたいオブジェクトを取り出します。
オブジェクトBがどのように作られるのかを気にすることなく、完成し たオブジェクトBをただ使うという目的を達成するために、コンテナから名前をキーにしてオブジェクトを取り出す、これがサービスロケータのパターンです。
オブジェクトAは、コンテナの外側でインスタンス化されます。コンテナの管理下にないこのようなオブジェクトでは、直接コンテナオブジェクトを道具として参照して使う必要があるわけです。たとえばSymfony Standard Editionに標準で用意されているコントローラクラスはコンテナの管理下にないため、サービスロケータ方式になっています。
必要なオブジェクトの受け口だけ用意して受け取る(受動的)
別の担当者Bさんは、オブジェクトBを開発しています。Bさんの視点だけをピックアップしたのが次の図です。
オブジェクトBの実装には、オブジェクトC(のインターフェイス)を使っています。このオブジェクトCは、さらにD、E・・・を使っているかもしれませんが、オブジェクトCから先はBさんの担当ではありません。ただ単にオブジェクトCを使い、自分の担当であるオブジェクトBの処理を実装したいだけです。
このプロジェクトでは、オブジェクトBは、必ずコンテナ経由で利用する、という取り決めがあると思ってください。つまり、オブジェクトBはコンテナの管理下にあるわけです。このような場合、オブジェクトBの生成時に、コンストラクタの引数や追加のセッター呼び出しによって、必要な依存オブジェクトをコンテナが自動的にセットするようにできます。オブジェクトBは、「受け取る道具の種類」をコンストラクタの引数で示してはいますが、自ら取り出しているわけではありません。
オブジェクトCがどのように作られるのかを気にすることなく、完成したオブジェクトCをただ使うという目的を達成するために、使いたいオブジェクトの受け取り口だけ用意して、コンテナがそこへ渡してくれる、というのがDIのパターンです。
まとめ
同じコンテナでも、それを使うオブジェクトがコンテナの管理下にあるかどうかで、使える手法が異なります。プロジェクトで利用するフレームワークとの兼ね合いで、コンテナ管理下におけない状況などがあります。
重要なのは、DIでもサービスロケータでも、依存の解決とオブジェクトの構築という仕事をオブジェクト自身からコンテナへ移しているのは同じだということです。これによって、Aさん、Bさんはそれぞれの担当範囲のみに集中できます。オブジェクトのコードから余計なものが取り除かれ、自分の仕事により局所化されるようになります。
参考
Advent Day 10: DI > SL ? « BEAR Blog
BEAR.Sundayチュートリアル・スクリーンキャスト
プログラミング道場生 kumamidori です。
5月31日に、Nagoya.php vol.5 に参加しました。
vol.5 のテーマは、「PHPフレームワークの1つであるBEAR.Sundayを触ってみよう」でした。 参加者全員で、BEAR.SundayワークショップWiki(チュートリアル)の内容に取り組みました。 私が見つけられた範囲だと、@kenji_sさん、@qckanemoto さんがブログにまとめられていますので、そちらをご覧頂ければと思います。記事の文末にそのリンクを貼ります。
BEAR.Sundayチュートリアル・スクリーンキャスト
この記事では、スクリーンキャストで、BEAR.Sundayチュートリアルのデモを、初心者なりの解説をまじえつつ紹介します。(見る人、誰もいないかもしれませんけれど・・・。)
スクリーンキャストNo.1:フレームワークの概要とインストール(youtubeページへのリンクです)
スクリーンキャストNo.2:リソースの作成、確認(youtubeページへのリンクです)
※今回動画を掲載することについて、フレームワーク作者に事前に許可を頂いております。
PHPカンファレンス関西について
BEAR.Sundayの作者である郡山さんは、6月28日(土)に開催されるPHPカンファレンス関西2014の基調講演をされる予定です。関西方面でご興味のある方は、懇親会の方にも申し込みされると良いかと思います。@hidenorigotoさんも遠方から来訪、参加されるそうです。
参考リンク
BEAR.Sundayに関するリンク
BEAR.Sunday
郡山さんによるRESTful Meetup vol.3におけるLT資料: HTTP IS ONE THING
PHPNW 2013(2) - Presentation « BEAR Blog
スクリーンキャスト内で引用した書籍
PHPメンターズブログにおける関連記事
PHPメンターズ -> WEB+DB PRESS PHP連載第5回「BEAR.SundayでRESTfulなシステム開発」を執筆しました
道場生ブログ -> BEAR.Sunday meetup #3 in Osaka 参加レポート
Nagoya.php vol.5 に関するリンク
Nagoya.php のFacebook
Nagoya.php vol.5 BEAR.Sunday workshopに参加しました — A Day in Serenity (Reloaded) — PHP, FuelPHP, Linux or something
Nagoya.php vol.5 で BEAR.Sunday のワークショップを行いました | QUARTET Engineers’ Blog
※6月29日追記:
名古屋の方から、「写真、撮っていましたよね?」とリマインドを頂いたので、貼っておきます。
BEAR.Sunday meetup #3 in Osaka 参加レポート
プログラミング道場生kumamidoriです。
PHPフレームワークの1つに、「BEAR.Sunday」があるのをご存知でしょうか。
リソース指向のOSSフレームワークで、郡山さん(@koriym)によって開発されています。
去年イギリスで行われたカンファレンス、「PHPNW2013」では、BEAR.Sundayのアーキテクチャを紹介するセッションがありました。
私は以前、旧バージョンにあたる「BEAR.Saturday」の方を仕事で使っていました。新しいBEAR.Sundayついては、初学者の状態で、さわる機会もあまりなかったのですが、気になっていました。2013年7月には、BEAR.Sunday meetup #2の主催をさせて頂いたこともありました。
そのようないきさつがあり、4月7日、BEAR.Sunday meetup #3 in Osakaを開催することになりました。 郡山さんに、PHPNW2013でのセッションをアップデートした内容で再演して頂きました。
参加者を引き込む素敵なセッションをして下さり、ありがとうございました。
また、会場提供を引き受けて下さった1x1株式会社の新原さん(@shin1x1)に、お礼申し上げます。
この記事では、セッション内容の抜粋と、個人的感想を書きます。
1. セッション内容の抜粋
1-1. なぜ新しいフレームワークを作るのか
- Quality と Agility の時代
Webアプリケーションは、長期的に改善し続けていく必要のあるものである。Quality と Agility の時代と言える。 Agilityとは、「すぐに変更することが可能である」ということ。
PHP5.3以降のPHPフレームワークには、単に「動くものを速く作る」のとは、少し違った流れがあった。 多くのPHPフレームワークが揃ってDIを採用したことは、その一例と言える。
- フレームワーク、アーキテクチャ
大事なのは、あなたは何をしたいのか?ということ。 「自分たちのドメインの問題」を解決するためのフレームワークを持つことに意味がある。
PHPNW2013の来場者が興味を持っていたのは、「次のアーキテクチャは何か?」ということだった。 たとえば、Symfony1 から 2 へ、Zend1 から 2 へ、成功したフレームワークはどれも、ユーザが「バージョンアップのための、大幅な書き直し」を経験してきた。 Symfony2 から 3 で、またあれをやらなければならないのか?!という問題がある。そういった問題を、どのような技術で解決できるのかという視点、アーキテクチャの選定、という意味で、新しいものを探そうという動機から、BEARのセッションを聞きに来てくれた。
1-2. PHPNW2013「A resource orientated framework using the DI /AOP/REST Triangle」再演
(※NW2013当時の、作者ご本人のプレゼンテーション内容紹介エントリーを見て頂く方がエッセンスが伝わると思うので、そちらをご参照頂ければと思います。 私の記事では、背景、前提となる知識の部分に話題を絞ってメモします)。
BEARはアプリケーションフレームワークだけれども、ライブラリを持たない。良いライブラリは既存でたくさんあるから、再発明の必要が無い。
そもそも、フレームワークとは何か?
広義の意味:
imposes a set of design constraints on end-user code.
エンドユーザのコードに対して、設計上の全体的な制約を与える。 (by Nate Abele)
狭義の意味:
「呼ぶ」側-「呼ばれる」側の関係が逆転して、「呼ぶ」側をフレームワークが最初からお膳立てし、「呼ばれる」側だけをユーザが書く。
BEARの場合は?:呼ぶ側もユーザが書く。
BEAR.Sundayは、3つのオブジェクトフレームワークを持つ。
(1) DI Framework
前提知識となる Dependency Inversion Principle (依存関係逆転の原則、DIP)についての話があったのですが、文末の参考リンクに詳しい解説があるので、ここでは省きます。
(2) AOP
たとえばあらゆるモジュールに散在してしまうロギングのような、 横断的関心事(Cross-Cutting Concerns)を分離することで、 モジュール間を疎結合とするプログラミングパラダイムのこと。
アプリケーションロジック(ログ、キャッシュ、etc…)とドメインロジック(コアの関心事)を分離する。
(3) REST(Hypermedia Framework)
オブジェクトをWebサービスのように扱う。
RESTとは:クライアントとサーバにWebは分かれている。決まったメソッドしか使えない。リクエストは1回だけで、ステートレスである。
このアーキテクチャを、OOPアプリケーションの内部に適用している。リソースとリソースをハイパーリンクによってつなぐことができる。
情報に真の意味での価値を与えるのはそのつながりである。
実装を直接書くのではなく、まず、抽象化された意図を記述する。次に、その意図に役割を与えて動かす(実装を結合する)。
A resource oriented framework using the DI/AOP/REST triangle from Akihito Koriyama
セッション内容については以上となります。
2. 個人的感想
下記が分からなかったので、今後調べていきたいと思いました。
他の言語、たとえばRubyでは、変更の安全性(ある1箇所を直したら、あちこちに影響が出たり、予想もしないところに作用が出たり、といったことを防ぐ)を、どう担保しようとしているのか?
複雑なロジックでも、DIのランタイムとコンパイルの分離で表現できるのか?
セッションの中で出てきた、「staticコールだとAOPはうまくいかない。インターフェイスでないとうまくいかない。」という話のくだりのところが理解できなかった。自動生成の仕組みを調べておきたい。
やはり、熟練者でないと、実際に使ってみないとよくわからないので、小さなモノを作ってみるところから始めてみたいと思います。
(今回一緒に主催をしてくれた @atakig さんが直立不動の写真を載せておきます)。
関連リンク
BEAR.Sunday公式ドキュメント
kawanamiyuuさんが作られたVagrantデモ
東京で2014年4月12日に行われた別のイベント「RESTful Meetup vol.3」におけるBEAR.Sunday紹介LT(郡山さんによる):HTTP IS ONE THING(<このスライド、下にも進めるのですよ!)
ウェブスター株式会社によりBEAR.Sundayで開発されているPen online
過去に開催されたイベント
BEAR.Sunday meetup #0
BEAR.Sunday meetup #1
BEAR.Sunday meetup #2
参考
BEAR.Sundayの紹介記事です。
WEB+DB PRESS PHP連載第5回「BEAR.SundayでRESTfulなシステム開発」を執筆しました
Dependency Inversion Principle (依存関係逆転の原則)、DIに関するリンクです。
Robert C. Martin - Dependency Inversion Principle(PDF)
山口大輔氏による日本語訳
Pieceの中のSymfony #3: Dependency Injectionコンポーネント