<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BEAR Blog</title>
	<atom:link href="http://www.bear-project.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bear-project.net/blog</link>
	<description>Because everything is a resource.</description>
	<lastBuildDate>Fri, 18 May 2012 06:52:49 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>DIP：Dependency Inversion Principle</title>
		<link>http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/</link>
		<comments>http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/#comments</comments>
		<pubDate>Fri, 18 May 2012 06:15:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[Dependency Inversion Principle]]></category>
		<category><![CDATA[DIP]]></category>
		<category><![CDATA[LoD]]></category>
		<category><![CDATA[Robert C. Martin]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1528</guid>
		<description><![CDATA[DIP Robert C. Martin氏による有名なオブジェクト指向設計（OOD）の原則Principles of OODがあります。そのうちDIP依存逆転原則はクラス同士の結合度をいかに減らすか、またはどちらに依存す...  <a href="http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/" class="more-link" title="Read DIP：Dependency Inversion Principle">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>DIP</h1>
<p>Robert C. Martin氏による有名なオブジェクト指向設計（OOD）の原則<strong>Principles of OOD</strong>があります。そのうちDIP依存逆転原則はクラス同士の結合度をいかに減らすか、またはどちらに依存すべきかを判定する原則です。</p>
<blockquote>
<ul>
<li>上位モジュールは下位モジュールに依存してはならない。両者は抽象に依存すべきである。</li>
<li>抽象は詳細（抽象の実装クラス）に依存してはならない。詳細は抽象に依存すべきである。</li>
</ul>
</blockquote>
<ul>
<li>オリジナル Robert C. Martin氏の<a href="http://www.objectmentor.com/resources/articles/dip.pdf">Dependency Inversion Principle (DIP) (PDF)</a></li>
<li><a href="http://www2.ocn.ne.jp/~yamagu/">山口大輔</a>さんによる<a href="http://www2.ocn.ne.jp/~yamagu/object/DIP-J.pdf">和訳版(PDF)</a></li>
<li><a href="http://d.hatena.ne.jp/asakichy/20090128/1233144989"> [オブジェクト指向設計原則]依存関係逆転の原則（DIP）: Strategic Choice: </a></li>
<li><a href="http://www.syboos.jp/sysdesign/doc/20080609145612887.html">Dependency Inversion Principle (DIP) &#8211; OO設計のDIP依存逆転原則: オブジェクト指向設計</a></li>
</ul>
<p>以下はオリジナルの論文の結びの言葉です。</p>
<blockquote><p>依存性逆転の原則は、<strong>オブジェクト指向技術で得られると言われる数多くの利益のうち、もっとも根幹にあたる部分に位置付けられます。</strong>この原則を適切に適用することは、再利 用可能なフレームワークを構築する上では不可欠なのです。また、変更に際して回復の早い(弾力的な)コードを書く上では決定的な重要性を持ちます。抽象とこまごまとしたものはそれぞれが分離さるので、コードはとてもメンテナンスしやすいものになります。</p></blockquote>
<p>BEAR.SundayではこのDIPを最大限に重要と考え、コード全域に渡って適用しています。<sup><a href="http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/#footnote_0_1528" id="identifier_0_1528" class="footnote-link footnote-identifier-link" title="実際にフレームワーク開発の前に着手したのがこの実現のためのDI systemのRay.Diです">1</a></sup></p>
<h2>実装ではなく抽象に依存する</h2>
<p>解説してる文章で最も短く簡潔なのが<a href="http://d.hatena.ne.jp/asakichy/20090128/1233144989">Strategic Choice</a>ブログの説明です。</p>
<blockquote><p>DIPを一言で説明すると「抽象に依存せよ」という経験則。<br />
    プログラムは具体的なクラスに依存してはいけない。<br />
    プログラム内の関係はすべて、抽象クラスかインターフェースで終結すべきである
</p></blockquote>
<p>BEAR.Sundayのクラスでは、以下のように依存は原則全て注入してもらう事を期待します。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @Inject<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setPrinter<span style="color: #009900;">&#40;</span>OutputDevice <span style="color: #000088;">$printer</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">printer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$printer</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>ここで大事なのはタイプヒンティング（この場合OutputDevice）を<strong>抽象</strong>、つまりインターフェイスかまたは抽象クラスにして具象クラスを<a href="http://php.net/manual/ja/language.oop5.typehinting.php">タイプヒント</a>にしないことです。タイプヒンティングを<strong>エラーチェックのための便利な機構とだけ捉えずDIPに従った設計のための仕組みとして考えます</strong>。</p>
<ul>
<li><a href="http://drupal.org/node/608152">Object-oriented code : Drupal</a></li>
</ul>
<h2>アンチパターン考察</h2>
<p>前回記事と今回のDIPを合わせて考えてアンチパターンになるのが以下のようなコードです。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">container</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'serviceA'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getB</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getC</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>このコードでは抽象への依存はなくコンテナに入った実装に依存しています(DIP違反）。メソッドチェーンで繋がれた依存の依存が持っている知識を前提としていて(LoD違反）オブジェクトの構成要素は暴露されています。こういったオブジェクトを探しまわるコードを止めて、インターフェイスを通じて依存を受け取るコードに変更します。</p>
<h2>BEAR.Resourceでは</h2>
<p>DIを用いてDIPを守る事は特にリソースクライアントのBEAR.Resourceを作成するときに有用性を特に実感しました。リソースクライアントのオブジェクトグラフは複雑です。最も簡単なコンストラクトに以下のようなコードが必要です。<sup><a href="http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/#footnote_1_1528" id="identifier_1_1528" class="footnote-link footnote-identifier-link" title="これでも何のスキーマも解釈できませんが">2</a></sup></p>
<pre>
$injector = new Injector(new Container(new Forge(new Config(new Annotation(new Definition)))), new EmptyModule)
$invoker = new Invoker($injector, new Linker, Manager(new HandlerFactory, new ResultFactory, new ResultCollection));
$resource = new Client(
    new Factory(new SchemeCollection),
    $invoker,
    new Request($invoker)
);
</pre>
<p>全ての依存をコンストラクタで手動で渡してるためにこんなに長くなっていますが、多くの役割をこなすリソースクライアントはそれぞれ関心が分離され別々のオブジェクトとなっています。</p>
<p>構成は複雑なのですが、DIPやLoDに従っていることで、各クラスの責務は適切なスコープをもちメンテナンス性は保たれているコードになっているのではと考えています。これをアンチパターンで示したようにオブジェクトを探し回してその実装に頼るコードにしてたらまた違った事になったかもしれません。</p>
<h2>Ray.DiでDIP</h2>
<p>昨日の記事をかいたあとにこのDIPの事を触れてなかった事を思い出し<sup><a href="http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/#footnote_2_1528" id="identifier_2_1528" class="footnote-link footnote-identifier-link" title="最大限重要と考えてたくせに&amp;#8211;;">3</a></sup>原文調べ直すとに「もっとも根幹にあたる部分に位置付けられます。」という記述を見つけてそうだ、そうだとなったのでこの記事を追加で記しました。BEAR.Sundayの機能をささえる大くの部分がリソース指向やAOPで実現されますが、それらのコードはこのDIPに従うための<a href="http://www.bear-project.net/blog/2012/04/di/">Ray.Di</a>で構築されています。</p>
<p>アプリケーション構築もまたDIPに従ったものが推奨されます。そしてそれをより容易に実践するためにトレイトによるインジェクション等の取り組みがRay.Diになされています。</p>
<ol class="footnotes"><li id="footnote_0_1528" class="footnote">実際にフレームワーク開発の前に着手したのがこの実現のためのDI systemのRay.Diです</li><li id="footnote_1_1528" class="footnote">これでも何のスキーマも解釈できませんが</li><li id="footnote_2_1528" class="footnote">最大限重要と考えてたくせに&#8211;;</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/05/dip%ef%bc%9adependency-inversion-principle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BEAR.Sunday Coding</title>
		<link>http://www.bear-project.net/blog/2012/05/cleancode/</link>
		<comments>http://www.bear-project.net/blog/2012/05/cleancode/#comments</comments>
		<pubDate>Thu, 17 May 2012 13:15:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Design Pattern]]></category>
		<category><![CDATA[Double Dispatch]]></category>
		<category><![CDATA[Informatin Expert]]></category>
		<category><![CDATA[LoD]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1483</guid>
		<description><![CDATA[The new era of PHP web development BEAR.Sundayの開発をスタートしたときに、web制作の現状や求められるものは？という視点で考察を行いました。その結果をスライドとしてまとめたの...  <a href="http://www.bear-project.net/blog/2012/05/cleancode/" class="more-link" title="Read BEAR.Sunday Coding">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>The new era of PHP web development</h2>
<p>BEAR.Sundayの開発をスタートしたときに、web制作の現状や求められるものは？という視点で考察を行いました。その結果をスライドとしてまとめたのがこの<a href="http://www.slideshare.net/akihito.koriyama/the-new-era-of-php-web-development">The new era of PHP web development.</a>というスライドです。<sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_0_1483" id="identifier_0_1483" class="footnote-link footnote-identifier-link" title="たまたま飛び入りでPHP勉強会で発表となりました">1</a></sup>約一年前です。</p>
<p>高速開発をセールスポイントにした従来のフレームワーク（もっといえばPHPそのものも）がQualityとAgility、つまり「ソフトウエア品質」に軸足を移している動きがあるのではないか？PHPの言語仕様だけでなく、作り手も求められてるものも変わってきてるのではないか？という考察でした。</p>
<p>一説によるとweb制作の仕事の80%はメンテナンスだそうです。どれだけ楽に早くつくれるか、という視点は人々の目を引きつけ、プロトタイピングの時に力を発揮し、初期の成功もより容易にします。 しかしそれは変更保守やスケーラビリティ、柔軟性、メンテナンス性と両立するか?という<strong>ソフトウエア品質</strong>の視点もそれ以上に重要と考えました。</p>
<h2>BEAR.Sunday Code</h2>
<p>BEAR.Sundayを完全にリライトすると決めた時、その機能設計と共に<strong>Clean Code</strong>での実装にも注力しようと思いました。フレームワークの機能提供は大事ですが、フレームワークがユーザーによって変更拡張可能かという点も同様に重要と考え、更にその柔軟性とメンテナンス性のためフレームワーク自身のコード品質も重要とも考えました。新規プロジェクトでBEAR.Saturdayではできなかったあの機能もこの機能もと実装中心に考えがちですが、むしろそれら新機能の実装の着脱が容易になる優れた設計こそに価値があると考えました。</p>
<p>設計とともにBEAR.SundayをCleanなコードでコーディングをするためにいくつかの原則を最初にたてました。最初にたてた原則にはこれまでにない色々な挑戦もありました。ある程度実装が進んだ今、その原則に従う事が現実的であったか、また有効であったかが明らかになってきました。この記事ではそれらのうちのいくつかを紹介します。<sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_1_1483" id="identifier_1_1483" class="footnote-link footnote-identifier-link" title="実際のコードには反省のある箇所もありリファクタリングの必要な箇所も残されています">2</a></sup><sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_2_1483" id="identifier_2_1483" class="footnote-link footnote-identifier-link" title="原則は他の「機能性」やリーダビリティを犠牲にしてよい鉄則ではなくて基本原則です、ある場所では破ってるとしたらそれは仕方なく、あるいは力足りず..という事もあります">3</a></sup></p>
<h2>適切なスコープ</h2>
<h3>Global ?</h3>
<p>どこからでも扱える変数<strong>グローバル変数</strong>の使用の抑制が一般化されている一方で、同じようにグローバルステートをもつクラスの<strong>スタティック変数</strong>はやグローバルな関数である<strong>staticメソッド</strong>の利用はそれほどでもないと思います。BEAR.Sundayではこれらの使用を最小限にする方針をたてました。</p>
<h3>スタティックコール</h3>
<p>スタティックコールはグローバルなメソッドです。インスタンスにせずどこからも呼び出しすることができます。つまりOOPでなく手続き型で、モックへの差し替えが難しくテスタビリティを下げる、等がさけるべき理由としてあげられています。<sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_3_1483" id="identifier_3_1483" class="footnote-link footnote-identifier-link" title="個人的にはスタティックコールより副作用のない事が保証される名前空間付き関数の方が良いのではと思いますがどうでしょう。">4</a></sup></p>
<ul>
<li><a href="http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/">Static Methods are Death to Testability</a></li>
<li><a href="http://stackoverflow.com/questions/3973109/static-methods-when-and-when-not">Static Methods : When and when not<br />
</a>
	</li>
<li><a href="http://nicksda.apotomo.de/2011/07/are-class-methods-evil/" title="Are Class Methods Evil?">Are Class Methods Evil?</a></li>
<p><a href="http://corfield.org/blog/post.cfm/Static_is_Evil" title="Static is Evil"></a></p>
<p><sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_4_1483" id="identifier_4_1483" class="footnote-link footnote-identifier-link" title=" 他にも&amp;#8221;static method&amp;#8221; evilで検索すると色々記事が出てきます。">5</a></sup>
</ul>
<p>BEAR.Sundayのクラスでスタティックコールを使用していのはRay.DiでDependency Injectorをつくるときと、アプリケーションインスタンスをつくるとき、この２つです。どちらもアプリケーションがbootされ、グローバルスコープの状態で最初期のルートオブジェクトを作成するためのメソッドとして実装しています。</p>
<p>これを問題ないと考えたのはブートされたばかりのアプリケーションはまだグローバル空間でグローバルステートのものを扱うのは自然と考えたからです。グローバル変数も同様です。下記の記事はオブジェクトの作成は問題ないとする考察です。</p>
<p><a href="http://simpleprogrammer.com/2010/01/29/static-methods-will-shock-you/" title="Static Methods will Shock You: When static methods can be good">Static Methods will Shock You: When static methods can be good</a></p>
<p>bootでグローバルなスコープしかなかったものが、様々な関心を取り扱い、それぞれの関心空間が作られていきます。その関心空間（スコープ）でグローバルなものを扱う事が問題なのです。シングルトンも同様です。インスタンスが１つしか無い事が問題ではなく、それがグローバルに適用されるという事が問題です。重要なのはスコープです。</p>
<h3>グローバルステートの環境依存も最小に</h3>
<ul>
<li>グローバルスコープのシングルトン</li>
<li>グローバルdefine</li>
<li>include_path</li>
</ul>
<p>BEAR.Sundayでは同一インスタンスで他のアプリのアプリケーションリソースやページを呼ぶ事を可能にするため、これらのグローバル依存を最小限にする必要があります。原則的にこれらを全て不使用にする方針は前述の例外を除いて守られています。Saturdayで３つしかなかった&#8221;define&#8221;も０にしました。</p>
<h2>デメテルの法則</h2>
<p><a href="http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%A1%E3%83%86%E3%83%AB%E3%81%AE%E6%B3%95%E5%89%87">デメテルの法則</a>とは「自分以外の構造やプロパティに対して持っている仮定を最小限にすべき」という原則です。これはBEAR.Saturdayで守られてない部分がありフレームワークを保守する身として後で反省のある部分となったとこです。以下のようなコードです。</p>
<pre lang="php">
$this->_resource->read($params)->link('entry')->set('user_entry');
</pre>
<p>このコードではread()メソッドの実行後は「readで取得したオブジェクト」に変わってしまっていて`link()`以降のメソッドでLoD違反になってました。この弊害というのはフレームワークの保守の時に実感しました。</p>
<p>BEAR.Sundayでのこのfluent interfaceによるリクエストにLoD違反はありません。</p>
<pre lang="php">
$this->resource->get->uri('app://self/greetings')->withQuery(['lang' => 'ja'])->eager->request();
</pre>
<p>最後のrequest()以外は全て$thisを返しています。この原則は設計も実装もずっとシンプルでテスト、保守がしやすいものになりました。</p>
<p>他でもほぼ守られてると思いますが例外はあります。Aura.Diを拡張して実装したRay.Diは元のAura.Diで
<pre>getA()->getB()->getC()</pre>
<p>系のコードをそのまま引き継いで違反してます。</p>
<h2>setter/getterの除去</h2>
<ul>
<li>
<a href="http://css.dzone.com/articles/how-remove-getters-and-setters">How to remove getters and setters</a>
</li>
<li><a href="http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html">Why getter and setter methods are evil</a></li>
<li>
<a href="http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html">More on getters and setters</a></li>
<li>
<a href="http://stackoverflow.com/questions/565095/are-getters-and-setters-evil">Are Getters and Setters evil?</a></li>
</ul>
<p>最初の記事にあるように<a href="http://ja.wikipedia.org/wiki/%E3%83%80%E3%83%96%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81">ダブルディスパッチ</a>や<a href="http://d.hatena.ne.jp/asakichy/20090208/1234047153">Information Expert</a>で、外部からオブジェクトのプロパティをなるべく利用しないようにし、またsetter/getterを通じてオブジェクトの内部構造を暴露しないようにします。</p>
<p>LoDの場合と同じくRay.Diはsetter/getter使ってますが、他はは大体守れてると思います。リソースも内部構造を曝す事なく情報を結合する<strong>リソースリンク</strong>があり、ビューにモデル(appリソース）のプロパティを渡すのではなく、モデルがビューを保持しモデルの構成要素がなるべく曝されない設計になっています。</p>
<p>またcode/bodyといったプロパティを必要とするリソースオブジェクトは、プロパティを公開（public）しています。このようなコードでリソースオブジェクトの構成要素が必要なときでもLoD違反にならないようにしています。<sup><a href="http://www.bear-project.net/blog/2012/05/cleancode/#footnote_5_1483" id="identifier_5_1483" class="footnote-link footnote-identifier-link" title="SaturdayのgetBody()は違反でした">6</a></sup></p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$resource</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app://self/user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">eager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">body</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_valid'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></div></div>
<h2>Conclusion</h2>
<p>他にも<a href="https://github.com/koriym/BEAR.Sunday/wiki/Overall-Design-Principles">沢山ある</a>のですが特に今回の挑戦としてた項目について説明しました。</p>
<p>大事なのはこれらの原則はあくまで原則で絶対守らなければならない<strong>鉄則ではない</strong>ということです。世にある様々なデザインパターンや設計原則は有用で学習すべきものが多くあると思うのですが、多くの場合その有用性、有効性も「場合による」事が少なくないと考えます。議論の別れるものもあるし、例えばここでアンチパターンとした「スタティックコール」が有用な場合はやはりあるでしょう。それを使ってるだけで「駄目」「いけてない」というような判断をする事は正しくありません。</p>
<p>逆に一般に良くないとされてる事でも使い方や場合によってはより正しく機能する事もあります。goto文やpublicプロパティの「いけてない使い方」だけをみて感情的な反応を示す事は、PHPの駄目コードだけをみてPHPそのものを批判する愚に似てるかもしれません。</p>
<p>プログラマの意図（インテンション）を表し簡潔で保守性の高いClean Codeを記述するのはいくらコーディングを重ねても難しいもので、またやりがいのある事でもあります。</p>
<p>BEAR.Sundayではこれまでになく注力したつもりですが、やはり反省も多く今後リファクタリングが必要なところも多くあると思います。そういう意味で少し恥ずかしいところもあるのですが、こういう意図を持って取り組んできたという記録です。</p>
<p><iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=koriymassoc-22&#038;o=9&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=4048676881" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<ol class="footnotes"><li id="footnote_0_1483" class="footnote">たまたま飛び入りでPHP勉強会で発表となりました</li><li id="footnote_1_1483" class="footnote">実際のコードには反省のある箇所もありリファクタリングの必要な箇所も残されています</li><li id="footnote_2_1483" class="footnote">原則は他の「機能性」やリーダビリティを犠牲にしてよい鉄則ではなくて基本原則です、ある場所では破ってるとしたらそれは仕方なく、あるいは力足りず..という事もあります</li><li id="footnote_3_1483" class="footnote">個人的にはスタティックコールより副作用のない事が保証される名前空間付き関数の方が良いのではと思いますがどうでしょう。</li><li id="footnote_4_1483" class="footnote"> 他にも&#8221;static method&#8221; evilで検索すると色々記事が出てきます。</li><li id="footnote_5_1483" class="footnote">SaturdayのgetBody()は違反でした</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/05/cleancode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>v0.2.0alpha</title>
		<link>http://www.bear-project.net/blog/2012/05/v0-2-0alpha/</link>
		<comments>http://www.bear-project.net/blog/2012/05/v0-2-0alpha/#comments</comments>
		<pubDate>Tue, 15 May 2012 15:10:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[BEARSunday]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1464</guid>
		<description><![CDATA[BEAR.Sunday v.0.2.0alpha v.0.2.0alphaをリリースしました。 今回のリリースはblogチュートリアルのためのサンプルアプリケーションの実装を中心に、CRUDアプリケーションを通してアプリ...  <a href="http://www.bear-project.net/blog/2012/05/v0-2-0alpha/" class="more-link" title="Read v0.2.0alpha">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>BEAR.Sunday v.0.2.0alpha</h2>
<p>v.0.2.0alphaをリリースしました。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/05/3a25d01f4b3257cb76efcdeadeb1feab.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/05/3a25d01f4b3257cb76efcdeadeb1feab.png" alt="" title="Hello, BEAR.Sunday" class="alignnone size-full wp-image-1465" /></a>
<p>今回のリリースはblogチュートリアルのためのサンプルアプリケーションの実装を中心に、CRUDアプリケーションを通してアプリケーションモジュールの構成や基本実装を中心に行ったものの結果です。</p>
<p>オブジェクトフレームワークとしては当初の設計の完成に近づき、APIフレームワーク、Webフレームワークの部分実装が加わったものが今回のリリースになります。</p>
<p>blogチュートリアルはCakePHPの<a href="http://book.cakephp.org/1.3/ja/view/1528/CakePHP%E3%83%96%E3%83%AD%E3%82%B0%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB">CakePHPブログチュートリアル</a>日本Symfonyユーザ会の <a href="http://symfony.gr.jp/docs/for-beginners/blog-tutorial/?sk=file&#038;so=asc">Symfony Blogチュートリアル</a>、<a href="http://docs.symfony.gr.jp/sf2-blog-tutorial/">Symfony2 Blogチュートリアル</a>、<a href="http://code.google.com/p/bear-project/wiki/blog">BEAR.Saturday Blogチュートリアル</a>で作成するものと同じもので、比較が容易になるように構成もそれぞれ似せています。同じアプリの制作という制約があり充分ではないですが、なるべくBEAR.Sundayの特徴が分かるようにしました。</p>
<p>ご感想、お気づきの点などあれば是非お聞かせ下さい。 <a href="https://twitter.com/#!/bearsunday">@BEARSunday</a></p>
<ul>
<li><a href="https://github.com/koriym/BEAR.Sunday">GitHub</a></li>
<li><a href="http://code.google.com/p/bearsunday/wiki/blog">blogチュートリアル</a></li>
</ul>
<ul></ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/05/v0-2-0alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object Framework &#8211; Ray.Aop</title>
		<link>http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/</link>
		<comments>http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 13:39:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[AOP alliance]]></category>
		<category><![CDATA[Method Interceptor]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1373</guid>
		<description><![CDATA[Apect Oriented Design メソッド・インターセプター 例えばテスト用途にどんな引き数が渡されても特定の同じ値を返さなければならないとします。 あるいはアジリティを重視した開発で、メソッド内のコードや利用...  <a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/" class="more-link" title="Read Object Framework &#8211; Ray.Aop">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>Apect Oriented Design</h1>
<h2>メソッド・インターセプター</h2>
<p><a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/rayaop011.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/rayaop011.png" alt="" title="rayaop011" class="alignnone size-full wp-image-1410" /></a><br />
例えばテスト用途にどんな引き数が渡されても特定の同じ値を返さなければならないとします。</p>
<p>あるいはアジリティを重視した開発で、メソッド内のコードや利用データベースが用意できていない段階でも適当に用意した値を返す必要があるとします。</p>
<p>このような場合、通常テスティングフレームワークを使いモックオブジェクトを生成して利用します。BEAR.SundayのRay.Diのモジュールでモックオブジェクトを用意して差し替える事もできます。しかしRay.Aopの提供するメソッドインターセプターを使えば更に簡単です。</p>
<p>メソッドインターセプターはメソッドの実行を乗っ取り<strong>代理実行</strong>します。モックオブジェクトは対象オブジェクトを入れ替えますが、インターセプターは対象オブジェクトとそれを利用するコンシュマークラスの間に割り込み（インターセプト）します。</p>
<p>まずは基本になるオリジナルのメソッド実行と同じ動作をするインタセプターのコードです。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/rayaop.012.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/rayaop.012.png" alt="" title="rayaop.012" class="alignnone size-full wp-image-1412" /></a>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> GreetingInterceptor implements MethodInterceptor<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; * (non-PHPdoc)<br />
&nbsp; &nbsp; * @see Ray\Aop.MethodInterceptor::invoke()<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> invoke<span style="color: #009900;">&#40;</span>MethodInvocation <span style="color: #000088;">$invocation</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$invocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">proceed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> &nbsp;<span style="color: #000088;">$result</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>MethodInterceptorインターフェイスのinvoke（実行）というメソッドにはMethodInvocation（メソッド実行）オブジェクト$invocationが渡されます。<br />
<br />
メソッド実行オブジェクトはメソッドの実行に必要な全ての知識（対象インスタンス、メソッド名、引き数等）を持っています。オリジナルのメソッドを実行するためには<em>$invocation->proceed();</em>を実行します。</p>
<p>この実行の前後に処理を記述したりすることで元も処理をまたぐ事ができます。引き数を操作したり変更したりすることもできます。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_0_1373" id="identifier_0_1373" class="footnote-link footnote-identifier-link" title="BEAR.SaturdayではAroundアドバイスとして実装されていものと同様のものです。">1</a></sup>またインターセプターを同じメソッドに複数適用することもできます。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.015.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.015.png" alt="" title="bear-sunday-tmp-111219033305-phpapp02-1.015" class="alignnone size-full wp-image-1418" /></a>
<p>テスト用に常にここのメソッドが&#8221;HelloTest&#8221;を返す為には以下のように変更します。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> GreetingInterceptor implements MethodInterceptor<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; * (non-PHPdoc)<br />
&nbsp; &nbsp; * @see Ray\Aop.MethodInterceptor::invoke()<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> invoke<span style="color: #009900;">&#40;</span>MethodInvocation <span style="color: #000088;">$invocation</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// $result = $invocation-&gt;proceed();</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> &nbsp;<span style="color: #0000ff;">&quot;HelloTest&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>このGreetingリソースに限らず、何のリソースでも使えるようにコンストラクタでmockを渡せるようにしたインタセプターはこのようになります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> MockResourceInterceptor<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mock</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> invoke<span style="color: #009900;">&#40;</span>MethodInvocation <span style="color: #000088;">$invocation</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mock</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span>　<br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>インターセプター・バインディング</h2>
<p>このインターセプターを特定のクラス、特定のメソッドにバインドするのも「モジュール」で行います。このバインドはsandbox\Resource\App\Greetingクラス（およびその継承したクラス）のどのメソッドにもMockInterceptorインターセプターを適用します。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindInterceptor</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">matcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subclassesOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sandbox\Resource\App\Greeting'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">matcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">any</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#91;</span><span style="color: #000000; font-weight: bold;">new</span> MockInterceptor<span style="color: #009900;">&#93;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>バインド対象を指定するためのマッチャーはアノテーションを指定したり、Callableオブジェクトを指定することもできます。</p>
<h2>@Cacheアノテーション</h2>
<p>BEAR.Sundayはいくつかのインターセプターを用意しています。その内、Cacheインターセプターは特に有用でしょう。このアノテーションはメソッド実行の結果を指定の秒数キャッシュします。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @Cache(60)<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">...</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>このインターセプターのソースを見てましょう。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>Cache <span style="color: #000088;">$cache</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$cache</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> invoke<span style="color: #009900;">&#40;</span>MethodInvocation <span style="color: #000088;">$invocation</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$class</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_class</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$invocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getThis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$invocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getArguments</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$saved</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$saved</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$saved</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$invocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">proceed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$annotation</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$invocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAnnotation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$annotation</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">time</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>インターセプターはというMethodInvocationインターフェイスを実装します。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_1_1373" id="identifier_1_1373" class="footnote-link footnote-identifier-link" title="これはJavaのAOPアライアンスのMethodInterceptorを元にしたもので、Google Guice, Spring, SeasorのAOPもこのAOPアラインアンスのインターフェイス群を実装しています。">2</a></sup> 引き数や対象メソッドをキーにキャッシュにを生成していて@Cacheアノテーションで指定された括弧内の秒数だけキャッシュデータを再利用するようになっています。</p>
<p>@Cacheアノテートされたされたリソースはアノテートがされただけでこれが実際にはどのインターセプターがバインドされるのかはこのクラスからは宣言していません。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_2_1373" id="identifier_2_1373" class="footnote-link footnote-identifier-link" title="前バージョンのBEAR.Saturdayでは実クラスを指定していて、アスペクトという関心の分離と適用はできたのですがそれが固定化されていました。">3</a></sup> このアノテーションが実際にどのインターセプターが適用されるのか、あるいはそもそもインターセプターが適用されない（開発時など）といった構成知識に関わりがありません。Ray.Diの@Injectアノテーションと同じように構成は利用される側でなく利用する側が持ちます。</p>
<h2>ランタイムインジェクター</h2>
<p>BEAR.Sundayのオブジェクトの実行は最初の１リクエストでオブジェクトフラフのコンストラクションを完了する<strong>コンパイル</strong>と、以降の<strong>ランタイム</strong>に分けられます。</p>
<p>コンパイルでリクエストをまたいで再利用可能なオブジェクトをつくるために、リクエスト毎にディペンデンシーを変えてインジェクトをしたりすることはできません。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_3_1373" id="identifier_3_1373" class="footnote-link footnote-identifier-link" title="またPDOなどのPHP標準組み込みオブジェクトもインジェクトできません。">4</a></sup></p>
<p>例えばDBオブジェクト<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_4_1373" id="identifier_4_1373" class="footnote-link footnote-identifier-link" title="PDOと違って組み込みオブジェクトではないので@Injectでコンパイル時にインジェクトすることは可能です">5</a></sup> のmaster / slaveをメソッドに応じて自動で選択するために、GET（読み込み）かそれ以外のメソッドでインジェクトを変えるという事はRay.Diのインジェクターではできません。</p>
<p>この場合インターセプターを使ってDBオブジェクトをメソッドにセットしてやることができます。</p>
<p>インターセプターはメソッド実行の情報が渡されるので、実行メソッド名をみてmaster/slaveのDBを選択することができます。master/slaveに限らずユーザーIDに応じたDB選択や、DBに応じた初期化などもインターセプターで記述できます。リソースをリクエストするクライントもそれを受けるappリソースも本来の仕事、つまり本質的関心(core concern)にのみ専念し、DBオブジェクトの準備というリソースをまたいだ<a href="http://netail.net/aosdwiki/index.php?%B2%A3%C3%C7%C5%AA%B4%D8%BF%B4%BB%F6">横断的関心事</a>(cross cutting concern)から<a href="http://ja.wikipedia.org/wiki/%E9%96%A2%E5%BF%83%E3%81%AE%E5%88%86%E9%9B%A2">関心を分離</a>することができます。</p>
<h4>Postsリソースクラス</h4>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Posts<br />
&nbsp;*<br />
&nbsp;* @Db<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Posts <span style="color: #000000; font-weight: bold;">extends</span> ResourceObject implements DbSetter<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Table<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var string<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$table</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'posts'</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* DB<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var Doctrine\DBAL\Connection<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Set DB<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @param Connection $db<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return void<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setDb<span style="color: #009900;">&#40;</span>Connection <span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Get<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return array<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT id, title, body, created, modified FROM <span style="color: #006699; font-weight: bold;">{$this-&gt;table}</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$stmt</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">body</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$stmt</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span>PDO<span style="color: #339933;">::</span><span style="color: #004000;">FETCH_ASSOC</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Post<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @param string &nbsp; $title<br />
&nbsp; &nbsp; &nbsp;* @param string &nbsp; $body<br />
&nbsp; &nbsp; &nbsp;* @param DateTime $created<br />
&nbsp; &nbsp; &nbsp;* @param DateTime $modified<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return \sandbox\Resource\App\Posts<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onPost<span style="color: #009900;">&#40;</span><span style="color: #000088;">$title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$body</span><span style="color: #339933;">,</span> <span style="color: #000088;">$created</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$modified</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">table</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$title</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'body'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$body</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">code</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">204</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h4>@Dbアノテーションクラス</h4>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Db<br />
&nbsp;*<br />
&nbsp;* @Annotation<br />
&nbsp;* @Target(&quot;CLASS&quot;)<br />
&nbsp;*<br />
&nbsp;* @package &nbsp; &nbsp;BEAR.Framework<br />
&nbsp;* @subpackage Annotation<br />
&nbsp;*/</span><br />
final <span style="color: #000000; font-weight: bold;">class</span> Db<br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h5>モジュール内でDbインジェクターをバインド</h5>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindInterceptor</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">matcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">annotatedWith</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BEAR\Framework\Annotation\Db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// クラスに@Dbとアノテートされた全てのクラス</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">matcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">any</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// 全てのメソッド</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#91;</span><span style="color: #000088;">$dbInjector</span><span style="color: #009900;">&#93;</span> <span style="color: #666666; font-style: italic;">// 複数バインドできます</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<h2>Conclusion</h2>
<p>Ray.Diのインジェクションシステムはコンシュマーとディペンデンシーの関係を疎にしアプリケーション構成を柔軟にします。コンパイルされた関係性は再利用されオブジェクトとオブジェクトの結びつき（オブジェクトグラフ）はリクエストをまたいでも変わりません。</p>
<p>対してRay.Aopのメソッドインターセプターはコンシュマーとメソッドの関係をダイナミックなものにします。メソッドをコールしてもそれが実際にオリジナルなメソッドをコールしたかにコンシュマーは関心を払いません。メソッド内ではDBデータを読み込んでるのに、バインドされたインターセプターはmemcacheからデータを読みその値を返し、オリジナルのメソッドはデータ更新の際の最初の１度しか呼ばれないかもしれません。関係性は外部で構成されます。</p>
<p>現代的なPHPフレームワークの多くは、アプリケーションコントローラーの役割を様々な関心をアスペクトととらえそれぞれの実装がなされています。例えばフィルターチェーンであったり、シグナルスロット、イベンドディスパッチャー、イベントサブスクライバー実装パターンや呼び方が違っても問題をアスペクトとしてそれぞれの解決をしようとしているのは同じように思えます。</p>
<p>Ray.AopでのAOPはコンシュマーにもサービスにもAOPフレームワークの依存がなく利用するためのサービスクラスには、イベント通知などイベントハンドリングのための仕事をする必要はありません。Ray.Diで生成されるサービスクラスはプロキシーにラップされ、該当メソッドの適用インターセプター知識をそれぞれが保持していて、イベントハンドリングがそれぞれのサービス<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_5_1373" id="identifier_5_1373" class="footnote-link footnote-identifier-link" title="詳しくはサービスを含んだプロキシー">6</a></sup>内で行われます。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_6_1373" id="identifier_6_1373" class="footnote-link footnote-identifier-link" title=" この仕組みはBEAR.Resourceでリソースそれぞれがレンダラーを持っているのと似ています。サービス（レンダラー、イベントハンドラー）にデータ（テンプレート、イベントシグナル）を渡すのではなく、オブジェクトがサービスを内包しているのです。 ">7</a></sup></p>
<p>現在のバージョンではRay.Aopを使ったアプリケーションコントローラー<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_7_1373" id="identifier_7_1373" class="footnote-link footnote-identifier-link" title="フォームや認証、セキュリティ、ログ">8</a></sup>の部分がまだ手つかずでその部分の本格的な実装はこれからです。しかしフレームワークやアプリケーションがコンシュマーとメソッドの関係をダイナミックにし外側から構成できる拡張性、関心の分離の促進によるソフトウエア品質の向上には期待をしています。<sup><a href="http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/#footnote_8_1373" id="identifier_8_1373" class="footnote-link footnote-identifier-link" title="一方このパターンを採用する事で発生するデメリットにも注意深く対処していかなければなりません。">9</a></sup></p>
<p>v0.1.0alphaリリースを機に<a href="http://www.bear-project.net/blog/2012/04/bear-resource/">BEAR.Resource</a>、<a href="http://www.bear-project.net/blog/2012/04/di/">Ray.Di</a>、Ray.AopとBEAR.Sundayのオブジェクトフレームワークというべきものについて記事を一つ一つかいてきました。Ray.Diはオブジェクトの生成を、Ray.Aopはそのオブジェクトのメソッドの利用にこれまでにない拡張性と機能性を与えます。そうやってできたオブジェクトにRESTという制約を被せ、オブジェクトの関係を（データではなく）DSLによって記述される関係性で結合しようとするのがBEAR.Resourceです。Ray.Diはオブジェクトグラフを、BEAR.Resourceはリソースグラフを構成しようとし、それぞれのリソースクラスは自らを構成しようとします。</p>
<ol class="footnotes"><li id="footnote_0_1373" class="footnote">BEAR.SaturdayではAroundアドバイスとして実装されていものと同様のものです。</li><li id="footnote_1_1373" class="footnote">これはJavaの<a href="http://aopalliance.sourceforge.net/">AOPアライアンス</a>の<a href="http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html">MethodInterceptor</a>を元にしたもので、Google Guice, Spring, SeasorのAOPもこのAOPアラインアンスのインターフェイス群を実装しています。</li><li id="footnote_2_1373" class="footnote">前バージョンのBEAR.Saturdayでは実クラスを指定していて、アスペクトという関心の分離と適用はできたのですがそれが固定化されていました。</li><li id="footnote_3_1373" class="footnote">またPDOなどのPHP標準組み込みオブジェクトもインジェクトできません。</li><li id="footnote_4_1373" class="footnote">PDOと違って組み込みオブジェクトではないので@Injectでコンパイル時にインジェクトすることは可能です</li><li id="footnote_5_1373" class="footnote">詳しくはサービスを含んだプロキシー</li><li id="footnote_6_1373" class="footnote"> この仕組みはBEAR.Resourceでリソースそれぞれがレンダラーを持っているのと似ています。サービス（レンダラー、イベントハンドラー）にデータ（テンプレート、イベントシグナル）を渡すのではなく、オブジェクトがサービスを内包しているのです。 </li><li id="footnote_7_1373" class="footnote">フォームや認証、セキュリティ、ログ</li><li id="footnote_8_1373" class="footnote">一方このパターンを採用する事で発生するデメリットにも注意深く対処していかなければなりません。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/04/object-framework-ray-aop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object Framework &#8211; Ray.Di</title>
		<link>http://www.bear-project.net/blog/2012/04/di/</link>
		<comments>http://www.bear-project.net/blog/2012/04/di/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 18:26:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[Annotation]]></category>
		<category><![CDATA[Aura.Di]]></category>
		<category><![CDATA[BEAR.Sunday]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Doctorine.Commons]]></category>
		<category><![CDATA[Guice]]></category>
		<category><![CDATA[Object Framework]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1296</guid>
		<description><![CDATA[Dependency Injection BEAR.Sundayではオブジェクトが必要とするインスタンスを、自ら取得しないでインジェクターに代入してもらうことを期待します。 コンストラクタやセッターメソッド経由で外部から...  <a href="http://www.bear-project.net/blog/2012/04/di/" class="more-link" title="Read Object Framework &#8211; Ray.Di">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>Dependency Injection</h2>
<p><a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.0102.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.0102.png" alt="" title="bear-sunday-tmp-111219033305-phpapp02-1.010" class="alignnone size-full wp-image-1368" /></a><br />
BEAR.Sundayではオブジェクトが必要とするインスタンスを、自ら取得しないでインジェクターに代入してもらうことを期待します。</p>
<p>コンストラクタやセッターメソッド経由で外部から代入されることをインジェクション（注入）、必要とするものをディペンデンシー（依存）と呼びます。ディペンデンシーを利用するクラスはコンシュマーと呼びます。</p>
<p>特に特定タスクを担当しオブジェクトがツールとして使うオブジェクトをサービスオブジェクトと呼びますが、依存はサービスオブジェクトに限りません。DB接続オブジェクトや、配列やスカラー値などの値も含みます。</p>
<p>前回記事の挨拶リソースに戻りましょう。このリソースはメッセージを返す為に、$messageデータを必要としています。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_0_1296" id="identifier_0_1296" class="footnote-link footnote-identifier-link" title="つまりこのリソースは$messageデータに依存しています">1</a></sup></p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Greetings <span style="color: #000000; font-weight: bold;">extends</span> AbstractObject<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'en'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hello World'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'ja'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Konichiwa Sekai'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'es'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hola Mundo'</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$greeting</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$greeting</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>$messageデータをクラスに固定で持たないで、外部から代入するように変更してみましょう。<br />
このようなセッターメソッドが必要です。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* @Inject<br />
&nbsp;* @Name(&quot;greeting_message&quot;)<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setMessage<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$message</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>固定されていたデータが外部から代入できるようになりました。</p>
<p>ディペンデンシーをセッターメソッド経由でインジェクションしてるので、これをセッターインジェクションと呼びます。 またコンストラクターにインジェクトするのをコンストラクターインジェクションと呼びます。BEAR.SundayはRai.DiというDIフレームワークを使っていますが、サポートするインジェクションはこの２つのみです。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_1_1296" id="identifier_1_1296" class="footnote-link footnote-identifier-link" title="プロパティにインジェクトするプロパティインジェクションはサポートされません。">2</a></sup></p>
<p>このインジェクションを行うのがディペンデンシーインジェクターです。インジェクターは決められたルールでオブジェクトのコンストラクションを行います。クラスをインスタンス化しディペンデンシーをインジェクトします。コンストラクション後に行われる初期化メソッドの呼び出しや、オブジェクト破棄の直前に呼ばれるメソッドの呼び出し予約など「オブジェクトライフサイクル」に関する設定も行います。BEAR.Sundayでは原則的に全てのオブジェクトの生成はこのディペンデンシー・インジェクターが行い、オブジェクトの中からディペンデンシーを取得することは推奨されません。</p>
<h2>インジェクションポイントと@Inject</h2>
<p>ユーザーがセッターメソッドに@Injectと注記（アノテート）することでRay.Diは『ここに依存の注入が必要だ』ということが分かります。この「外部からの代入を期待する部分」を<strong>インジェクションポイント</strong>と呼びます。</p>
<p>※注）アノテーションはDoctrine.CommonsのAnnotationを使用していて、このアノテーションを使うためのuse文が必要です。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Ray\Di\Di\Inject<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Ray\Di\Di\Named<span style="color: #339933;">;</span></div></div>
<p>インジェクションポイントに実際に何をセットするかは<strong>モジュール</strong>で設定します。モジュールではインジェクションポイントとインスタンスをバインドします。バインドの方法はいくつかありますがここでは特定の名前をつけてインジェクションポイントを指定する方法を使用していています。</p>
<p>実際のモジュールのコードはこのようになります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> AppModule <span style="color: #000000; font-weight: bold;">extends</span> AbstractModule<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'en'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hello World'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'ja'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Konichiwa Sekai'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'es'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hola Mundo'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">named</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'greeting_message'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toInsntance</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>インジェクターの生成とオブジェクトグラフ生成</h2>
<p>インジェクターを使ってこのクラスにディペンデンシーをインジェクトしてインスタンスを取得します。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$injector</span> <span style="color: #339933;">=</span> Injector<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #000000; font-weight: bold;">new</span> AppModule<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$injector</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name\space\Greeting'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>モジュールにはインジェクションポイントに対してどのインスタンスを提供するかという、いわばアプリケーションの構成知識が凝縮されています。その構成知識を使ってインジェクターはオブジェクトのコンストラクション（生成、インジェクト、ライフサイクルのセット）を行いインスタンスを返します。</p>
<h2>インジェクションの連鎖とオブジェクトグラフ</h2>
<p>ディペンデンシーインジェクションは専用のライブラリを使わなくても、手動でも行う事ができます。</p>
<p>たとえばUserクラスはDbクラスのインスタンスが必要でDbクラスはDB接続情報の文字列が必要だとします。これを手動のインジェクトするためには例えばこのようなコードが必要でしょう。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$dsn</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_ENV</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'master_db'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Db<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dsn</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000088;">$db</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>一行だとこうです</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Db<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_ENV</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'master_db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>このコードで明らかなのは、依存に依存があればその「依存の依存」から先に用意して順番に次の依存に渡さなければならないことです。Userクラスを生成する前に、DBオブジェクトの生成が完了してる必要があります。DBオブジェクトを生成するにはDB接続情報を取得しておく必要があります。これは通常のプログラムではごく当たり前のことです。</p>
<p>ところがRay.DIはUserクラスを作る前にDbオブジェクトを予め作っておく必要はありません。オブジェクトの構成知識を知っているインジェクターは必要な依存を遡って生成、インジェクトしてオブジェクトグラフをコンストラクションします。</p>
<p>例をあげます。</p>
<p>Userクラスを生成するときにRay.DiはそのクラスをつくるためにはDbオブジェクトが必要だと言う事を検知します。Dbオブジェクトを生成しようとしますが、ところがその生成にはDB接続情報が必要とも検知します。インジェクターがもつ構成知識でDB接続情報は得られます。得られた情報を使ってDBオブジェクトを生成します。そうやって依存の依存を順番に辿り依存性の解決（Dependency Resolution)を行い元のインスタンスを生成します。依存がツリー構造になっているこのオブジェクトをオブジェクトグラフと呼びます。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.035.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02-1.035.png" alt="" title="Object Graph" class="alignnone size-full wp-image-1370" /></a>
<h2>コンストラクションの再利用</h2>
<p>BEAR.Sundayではプログラムの中でいつでもインジェクターを使い必要なインスタンスをオンデマンドで生成できますが、実際にはほとんどその出番はありません。boot時のルートオブジェクトグラフ（ページリソースやリソースクライアント）が生成される時に必要なオブジェクト、またはファクトリーの生成が全て完了するからです。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_2_1296" id="identifier_2_1296" class="footnote-link footnote-identifier-link" title="現在のBEAR.Sundayで登場する独立したオブジェクトはアプリケーションはappリソースを除くと基本的には３つしかありません。アプリケーションとリソースクライアントとページリソースです。その他のオブジェクトをそれらの「ルートオブジェクト」を構成するプロパティでしかない場合がほとんどです。
">3</a></sup></p>
<p>前バージョンBEAR.Saturday (2008年）ではアプリケーションスクリプトからnew演算子を取り除くことが一つの目標でしたが、BEAR.Sundayではフレームワークサイドでもnewの利用はほとんどありあません。オブジェクトはコンストラクションされるとAPCのストレージに格納され、リクエストをまたいで再利用されます。</p>
<p>つまり現在のBEAR.Sundayではリクエスト毎に異なった処理をコンストラクタで記述することはできません。この制約はメリットとデメリットがあります。オブジェクトシリアライズ前提のためシリアライズできないクロージャや組み込みオブジェクトをコンストラクション時にプロパティにセットできません。一方、固定化されたオブジェクトグラフとより安定したフロー、強力で容易なキャッシュ機構、アノテーションやDI、AOP等を採用しながらも維持している強力なパフォーマンス等は大きなメリットです。</p>
<p>再利用はオブジェクトグラフの膨大な取得コスト<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_3_1296" id="identifier_3_1296" class="footnote-link footnote-identifier-link" title="アノテーションが必要とするコメント文のパースだけでなくアノテーションの名前解決のためのPHPスクリプトのパースも行われてます">4</a></sup> を最小限にします。30,000を超えるindexページのファンクションコールは500以下になり、実行速度は数十倍になっています。</p>
<p>オブジェクトのコンストラクタは基本的にサービス開始の最初の１リクエストしか通りません。その特徴をv0.1.0alphaインストールの時に用意されるindexページでみてます。</p>
<h5>indexページ画面</h5>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/77289491623cb7d47294d7b9e69ed064.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/77289491623cb7d47294d7b9e69ed064.png" alt="" title="Indexページ" class="alignnone size-full wp-image-1371" /></a>
<h5>indexページリソーススクリプト</h5>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Index <span style="color: #000000; font-weight: bold;">extends</span> Page<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">use</span> ResourceInject<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'greeting'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span><span style="color: #0000ff;">'Hello, BEAR.Sunday.'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'version'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'php'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'BEAR'</span> <span style="color: #339933;">=&gt;</span> Framework<span style="color: #339933;">::</span><span style="color: #004000;">VERSION</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'extentions'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'apc'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apc'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apc'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'memcache'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'memcache'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'memcache'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'mysqlnd'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mysqlnd'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mysqlnd'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'pdo_sqlite'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'pdo_sqlite'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'pdo_sqlite'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'Xdebug'</span> &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Xdebug'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Xdebug'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'xhprof'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'n/a'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Get<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$cache</span> <span style="color: #339933;">=</span> apc_cache_info<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'apc'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">'total'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cache</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'num_entries'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">'size'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cache</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mem_size'</span><span style="color: #009900;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// page / sec</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'performance'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">resource</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app://self/performance'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>コンストラクタではPHPのバージョンやフレームワークのバージョンやエクステンションの情報を自身のコンテンツとしてセットしています。これらの情報はリクエスト毎に変わる事のないスタティックなものです。</p>
<p>このコンストラクタはサービス開始時に1度しかリクエストされず、バージョンやエクステンションの情報が入ったコンテンツは再利用されます。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_4_1296" id="identifier_4_1296" class="footnote-link footnote-identifier-link" title="例えばYAMLファイルのCSVファイルのパースなどをコンストラクタで行いコンテンツとしてセットすると再利用されるので個別にキャッシュしたりする必要がありません。">5</a></sup></p>
<p>一方、GETリクエストに対応するメソッドではリクエスト毎にコールされるので、変化するパフォーマンスやAPC情報はリクエスト毎にセットされます。</p>
<p>スタティックなリソースコンテンツとダイナミックなリソースコンテンツは分離され適した動作をしています。</p>
<h2>トレイト・インジェクション</h2>
<p>違うクラスでも求める依存が同じなら、同じセッターが利用できます。セッターメソッドはクラスをまたいで横断的に再利用できます。モジュールに新たな設定はありません。<br />
メソッドの横断的利用、PHP5.4の新機能のtraitにすると便利で表記も簡潔になります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Ray\Di\Di\Inject<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Ray\Di\Di\Named<span style="color: #339933;">;</span><br />
<br />
trait MessageInject<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$message</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @Inject<br />
&nbsp; &nbsp; &nbsp;* @Name(&quot;greeting_message&quot;)<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setMessage<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$message</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>アノテーションのuse文も入っているので、利用クラスでは簡単にインジェクションが表記できます。まとめるとこうなります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Greetings <span style="color: #000000; font-weight: bold;">extends</span> AbstractObject<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">use</span> MessageInject<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$greeting</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$greeting</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>プロバイダー<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_5_1296" id="identifier_5_1296" class="footnote-link footnote-identifier-link" title="このセクションはstackoverflowの記事を元にしています。http://stackoverflow.com/questions/2504798/dependency-injection-in-constructors ">6</a></sup></h2>
<p>Day.DiによるDIは次の２つのパートで成り立っています。</p>
<ul>
<li>モジュールでのオブジェクトコンストラクション（Construction）</li>
<li>コンシュマーでの利用（Execution）</li>
</ul>
<p>コンストラクションはモジュールで完了させ、コンシュマーでは利用だけを行います。</p>
<p>肝心なのはコンストラクションとエクスキューションを完全に分離して、混ぜないことです。コンシュマーにディペンシーインジェクターやサービスコンテナを渡したりする事は推奨されません。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_6_1296" id="identifier_6_1296" class="footnote-link footnote-identifier-link" title="コンシュマーがインジェクターを使ってサービスを取得することは、デメテルの法則（最小知識の法則）に違反します。">7</a></sup><sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_7_1296" id="identifier_7_1296" class="footnote-link footnote-identifier-link" title="例外はそのコンシュマーがファクトリークラスの場合です。BEAR.Sundayで唯一インジェクターを依存として受け取りオブジェクトコンストラクションをしてるのはリソースのnewInstance()メソッドです。">8</a></sup></p>
<p>コンシュマー内で新しいインスタンスが都度欲しい時は<strong>プロバイダー</strong>を使います。プロバイダーは最小のファクトリーで、引き数なしのget()というメソッドだけを持ちます。たとえばテンポラリーファイルのハンドルが都度、複数欲しいなら(Provider)$tmpFilePorviderをインジェクトしてもらって、このように使います。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$tmpFile1</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tmpFileProvider</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$tmpFile2</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tmpFileProvider</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>プロバイダーはどのようにインスタンスを作るかという知識を全て持っています。引き数は渡す事ができず、最小化されたこのファクトリーに伝える事ができるのは生成のタイミングだけです。</p>
<p>なお、newは絶対に使っていけないというわけではありません。ごく小さなオブジェクトやPHPの組み込みオブジェクトなどは問題ないでしょう。</p>
<h2>Conclusion</h2>
<p>この記事では、BEAR.Sundayアプリケーションの役割と働きをみてきました。Ray.Diは<a href="http://code.google.com/p/google-guice/">Google Guice</a>のクローンです。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_8_1296" id="identifier_8_1296" class="footnote-link footnote-identifier-link" title="Guiceが使われているGoogleの代表的なプロダクトにAdSenseがあります">9</a></sup> 全ての機能が移植されてるわけではありませんが、ここで紹介した機能以外にも沢山の機能があります。<a href="http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html">Doctrine.Commons.Annotation</a>ライブラリを使い、AuraというPHP5.4フレームワークの<a href="https://github.com/auraphp/Aura.Di">Aura.Di</a>ライブラリを拡張して作成しています。またRay.Diインジェクター自身の依存も手動でインジェクトされ拡張可能です。</p>
<p><a href="http://code.google.com/p/rayphp/">Ray.Di  &#8211; Guice style annotation-driven dependency injection framework for PHP</a></p>
<p>インジェクションポイントとディペンデンシーのバイディングはモジュールで設定し、インジェクターはどのオプジェクとが求められればどのインスタンスを渡すかという知識を持っています。モジュールはクラスをどのようにコンストラクトするかではなく<strong>求められた依存に対してどのインスタンスを渡すか</strong>という設定が行われています。そのため同じ依存を要求する違うクラスに新たな設定は必要なく、セッターメソッドのtraitを使ってより簡素な記述でディペンデンシーが取得できます。</p>
<p>Ray.Diの特徴はオブジェクトの生成と利用が完全に分離されていること<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_9_1296" id="identifier_9_1296" class="footnote-link footnote-identifier-link" title="利用クラスでサービスコンテナへの依存がない">10</a></sup>、モジュールでのDSLによるバインディング、APCを使ったオブジェクトグラフコンストラクションの再利用等です。<sup><a href="http://www.bear-project.net/blog/2012/04/di/#footnote_10_1296" id="identifier_10_1296" class="footnote-link footnote-identifier-link" title="コンストラクションは常にキャッシュされ、再利用されることを考慮したコーディングが必要です。">11</a></sup></p>
<p>Ray.Diは<strong>可変点の明確化と最小化</strong>というBEAR.Sundayのアーキテクチャ全体を通しての原則を支持します。</p>
<p>またRay.Diはモジュールで特定メソッドの実行にインターセプターをバインドすることが可能で、アスペクト指向プログラミングが利用できます。BEAR.Sundayではフレームワークやアプリケーションの動作や役割を様々なアスペクトの集合だと考えています。次回の記事ではAOPをサポートすRay.AopのBEAR.Sundayでの役割、アスペクト指向デザイン(AOD)により実装されたアプリケーション機能を紹介します。</p>
<ol class="footnotes"><li id="footnote_0_1296" class="footnote">つまりこのリソースは$messageデータに依存しています</li><li id="footnote_1_1296" class="footnote">プロパティにインジェクトするプロパティインジェクションはサポートされません。</li><li id="footnote_2_1296" class="footnote">現在のBEAR.Sundayで登場する独立したオブジェクトはアプリケーションはappリソースを除くと基本的には３つしかありません。アプリケーションとリソースクライアントとページリソースです。その他のオブジェクトをそれらの「ルートオブジェクト」を構成するプロパティでしかない場合がほとんどです。<br />
</li><li id="footnote_3_1296" class="footnote">アノテーションが必要とするコメント文のパースだけでなくアノテーションの名前解決のためのPHPスクリプトのパースも行われてます</li><li id="footnote_4_1296" class="footnote">例えばYAMLファイルのCSVファイルのパースなどをコンストラクタで行いコンテンツとしてセットすると再利用されるので個別にキャッシュしたりする必要がありません。</li><li id="footnote_5_1296" class="footnote">このセクションはstackoverflowの記事を元にしています。http://stackoverflow.com/questions/2504798/dependency-injection-in-constructors </li><li id="footnote_6_1296" class="footnote">コンシュマーがインジェクターを使ってサービスを取得することは、<a href="http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%A1%E3%83%86%E3%83%AB%E3%81%AE%E6%B3%95%E5%89%87">デメテルの法則（最小知識の法則）</a>に違反します。</li><li id="footnote_7_1296" class="footnote">例外はそのコンシュマーがファクトリークラスの場合です。BEAR.Sundayで唯一インジェクターを依存として受け取りオブジェクトコンストラクションをしてるのはリソースのnewInstance()メソッドです。</li><li id="footnote_8_1296" class="footnote">Guiceが使われているGoogleの代表的なプロダクトにAdSenseがあります</li><li id="footnote_9_1296" class="footnote">利用クラスでサービスコンテナへの依存がない</li><li id="footnote_10_1296" class="footnote">コンストラクションは常にキャッシュされ、再利用されることを考慮したコーディングが必要です。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/04/di/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BEAR.Resource</title>
		<link>http://www.bear-project.net/blog/2012/04/bear-resource/</link>
		<comments>http://www.bear-project.net/blog/2012/04/bear-resource/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 17:03:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1178</guid>
		<description><![CDATA[BEAR.SundayはDI、AOP、REST、この３つの技術をコアにしたオブジェクトフレームワークをベースにしています。 このオブジェクトフレームワークがある程度完成したのを機に、今回v0.1.0alphaとして一旦ま...  <a href="http://www.bear-project.net/blog/2012/04/bear-resource/" class="more-link" title="Read BEAR.Resource">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>BEAR.Sundayは<strong>DI</strong>、<strong>AOP</strong>、<strong>REST</strong>、この３つの技術をコアにしたオブジェクトフレームワークをベースにしています。<br />
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/2bear-sunday-tmp-111219033305-phpapp02.002-001.png"><img class="alignnone size-full wp-image-1257" title="2bear-sunday-tmp-111219033305-phpapp02.002-001" src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/2bear-sunday-tmp-111219033305-phpapp02.002-001.png" alt="" /></a><br />
このオブジェクトフレームワークがある程度完成したのを機に、今回v0.1.0alphaとして一旦まとめました。<sup><a href="http://www.bear-project.net/blog/2012/04/bear-resource/#footnote_0_1178" id="identifier_0_1178" class="footnote-link footnote-identifier-link" title="HelloWorldしか出ない状態が長く続いたのにも関わらずソースをみたり関心を持ってもらった方がおられました。ありがとうございます">1</a></sup> まだ実用レベルではなくこれからこのオブジェクトフレームワークの上に、APIフレームワーク、webアプリケーションフレームワークと、フレームワークのレイヤーを重ねていく予定です。</p>
<p>この記事では現在のv0.1.0alpha実装からBEAR.Sundayの特徴を紹介します。</p>
<h2>リソースオブジェクト</h2>
<p>BEAR.Sudayで中心になるのがリソースオブジェクトです。MVCで言うとモデルに近いものですがwebからアクセスされる最初のリソースレイヤーの<strong>pageリソース</strong>はコントローラーのように振る舞います。</p>
<p>それぞれのリソースはURIで表すことができ、スキーマに応じて処理の仕組みが変わります。最も標準的なものはリソースURIとPHPクラスがマップされるリソースオブジェクトです。HTTPのリクエストメソッドに準じたインターフェイスメソッドを持ち、リクエスト処理を記述します。役割に応じてpageリソースやappリソースとスキーマや呼び方は代わりますが基本的な仕組みは同じです。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.005-001.png"><img class="alignnone size-full wp-image-1263" title="page resource" src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.005-001.png" alt="" /></a>
<p>ウエブページのようなオブジェクトと思ってみてください。</p>
<p>例えばGETリクエストすればリクエスト用のメソッドがコールされ、結果でもあるリソースオブジェクト自身が帰ってきます。</p>
<p>まずはHello Worldページです。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Hello <span style="color: #000000; font-weight: bold;">extends</span> Page<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">body</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Hello '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>$nameを受け取り連結して返すだけのページです。bodyプロパティに代入して自身を返してる事に注目してください。</p>
<p>このページクラスは以下のように表記しても同じです。<sup><a href="http://www.bear-project.net/blog/2012/04/bear-resource/#footnote_1_1178" id="identifier_1_1178" class="footnote-link footnote-identifier-link" title="シンタックスシュガー ">2</a></sup>文字列を返しても、クライアントにはbodyプロパティがセットされたオブジェクトが返ります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Hello <span style="color: #000000; font-weight: bold;">extends</span> Page<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'Hello '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>４つの公開されたプロパティ</h2>
<p>リソースクラスは以下の４つのpublicプロパティを持ちます。 </p>
<li>リソースコード</li>
<li>リソースメタ情報（ヘッダー）</li>
<li>リソースコンテンツ（リソース状態）</li>
<li>リソース表現</li>
<p>コードはHTTPステータスコードに準じたリソースの状態がはいっています。リソースの本質的な値はリソースコンテンツに入っていますが、クライアントが利用するリソース表現は別のプロパティが用意されています。</p>
<p>このHelloページリソースではリソーススコンテンツ$bodyプロパティをセットしてクライアントに返しています。</p>
<h2>レイヤード・リソース</h2>
<p><a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.005.jpg"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.005.jpg" alt="" title="Layerd Resource" class="alignnone size-full wp-image-1301" /></a><br />
pageリソースはwebクライアウントから最初にコールされるリソースレイヤーです。多くの場合、（更に関心を細分化した）appリソースをページからリクエストします。コントローラーがモデルをリクエストするようなもので、pageリソースは<strong>pageコントローラー</strong>、appリソースは<strong>内部APIとして振る舞うモデル</strong>として機能します。</p>
<p>最初の例の単純な例のpageリソースはコントローラーとして機能するよりも、リソースコンテンツを変更することで自身を構成しています。自身がレスポンスオブジェクトのようですがこれは不作法なことではありません。リソースは関心に応じてレイヤリングしますが、単純なHelloページではそのページだけで完結する場合もあるでしょう。一方、appリソースでも必要があれば関心にレイヤリングを適用して、適切なネストのレイヤーを持つのが良いでしょう。</p>
<p>最初にwebブラウザのリクエストURIに応じてルートされたpageリソースがリクエストされます。pageリソースはappリソースやその他のリソースをリクエストしますが、他のpageリソースもリクエストすることができます。階層構造MVCのように振る舞います。</p>
<h2>アプリケーション(app)リソース</h2>
<p>アプリケーションリソースはいわば内部APIです。MVCでの主役がMであるように、BEAR.Sundayでもアプリケーション価値の多くはこのappリソースにあります。<sup><a href="http://www.bear-project.net/blog/2012/04/bear-resource/#footnote_2_1178" id="identifier_2_1178" class="footnote-link footnote-identifier-link" title="一方、pageリソースの役割はリクエストURIに応じて複数のappリソースをアクセスする事がほとんどです。">3</a></sup></p>
<p>appリソースの簡単な例をコードで紹介します。$lang(言語)を引数で渡すと挨拶文字列を返す 「挨拶リソース」です。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Greetings <span style="color: #000000; font-weight: bold;">extends</span> AbstractObject<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'en'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hello World'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'ja'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Konichiwa Sekai'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">'es'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Hola Mundo'</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$greeting</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$greeting</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>これはpageリソースで説明したように、以下のコードと同じものです。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">body</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>挨拶のデータは$messageプロパティに格納されていて、引数$lang（言語）によって指定されたメッセージを返します。このリソースクラスはonGetメソッドがあり、GETリクエストだけを行う事ができます。</p>
<p>リソースクライアントからはのリクエストはこのようにして作る事ができます。withQuery()メソッドで与えてるのは順番による引数ではなくて、変数名を指定した名前付き引数（named parameter)であることに注意してください。引数の順番は関係ありません。</p>
<h2>リソースリクエスト</h2>
<p>リソースリクエストは以下のように記述します。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resource</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app://self/greeting'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">withQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lang'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ja'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>この文で作られたのは<strong>リクエスト</strong>です。このリクエストを実際に行うにはこのリクエストオブジェクトをクロージャのように扱います。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>リクエストは再利用することができます。引数を指定して指定した名前付き引数に追加、上書きすることができます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lang'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'en]);</span></div></div>
<h3>イーガーリクエスト</h3>
<p>リクエストの結果をすぐに求めるにはリクエストに eagerをつけます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resource</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app://self/greeting'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">-&gt;</span><span style="color: #004000;">withQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lang'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ja'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">-&gt;</span><span style="color: #004000;">eager</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>この文ではすぐにリクエストが行われます。</p>
<h2>リソースのレンダリング</h2>
<p>リクエストにより求められたリソースオブジェクトはプロパティにリソースの状態を持っています。プロパティを直接使う事もできますが、それよりオブジェクトとして利用するのがスマートです。オブジェクトはコンテキストに応じて評価されます。</p>
<p>連想配列として扱うとリソースコンテンツのエレメントが取り出せます。例えばユーザーリソースのID等です。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// $result-&gt;body['id'] と同じ</span></div></div>
<p>オブジェクトなのでメソッドを利用することはもちろんできます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">log</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>文字列として扱うと、そのリソースはコンテンツを表現に変えようとします。</p>
<p>BEAR.Sundayではリソースからデータを受け取ってテンプレートエンジンに渡すのではなく、<strong>リソースがテンプレートエンジンを保持</strong>し（データを外部に公開することなく）<strong>自身がレンダリング</strong>を行います。 </p>
<p>図をご覧下さい。</p>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.008.jpg"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.008.jpg" alt="" title="Web MVC" class="alignnone size-full wp-image-1303" /></a>
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.009.jpg"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/bear-sunday-tmp-111219033305-phpapp02.009.jpg" alt="" title="BEAR.Resource" class="alignnone size-full wp-image-1304" /></a>
<p>存在するリソースの１つ１つのオブジェクトがレンダラー（Viewオブジェクト）を保持します。<sup><a href="http://www.bear-project.net/blog/2012/04/bear-resource/#footnote_3_1178" id="identifier_3_1178" class="footnote-link footnote-identifier-link" title="アプリケーションスコープでシングルトン">4</a></sup>　</p>
<p>例えばユーザーリソースのコンテンツは以下のようなものだとします。</p>
<pre>$user->body = ['name' => 'koriym', 'gender' => 'male']</pre>
<p>このJSON表現はこうなります。</p>
<pre>{"name":"koriym","gender":"male"}</pre>
<p>このレンダリングはjson_encode()関数を使うだけの単純なものでしょう。</p>
<p>また、HTML表現は例えば以下のようなものになります。リソース専用のテンプレートを用意してレンダリングしています。</p>
<pre>&lt;span id="user">ユーザー名:koriym 性別:male &lt;/span></pre>
<p>リソースは自身の構成やコンテンツに関して関心を持ちますが、表現には直接関心をもたず、セットされたリソースレンダラーに自身（$this)を渡してレンダリングを命じます。</p>
<p>レンダリングはリソースオブジェクトが文字列として評価されたときに行われます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$user</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">// または</span><br />
<span style="color: #000088;">$userHtml</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$user</span><span style="color: #339933;">;</span></div></div>
<p>レンダラーの保持はオプションです。もしリソースがレンダラーを持たなくても、コンテンツが文字列として評価可能ならコンテンツを表現にします。リソースコンテンツが文字列表現ができないフォーマット（例えばarray型）で、レンダラーも持たないときに文字列として評価されれば文字列&#8221;を返します。</p>
<h2>リソースリクエストのレンダリング</h2>
<p>リソースリクエストが文字列として扱われたときには、リクエストを行い、その結果をレンダリングした結果の文字列が得られます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$request</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">// または</span><br />
<span style="color: #000088;">$userHtml</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$request</span><span style="color: #339933;">;</span></div></div>
<h2>レイジーリクエストとレイジーレンダリング</h2>
<p>リソースクライアントが生成したリクエストオブジェクトは文字列として評価されるときに初めてリクエストを行います。</p>
<p>v0.1.0alphaでインストールされるindexデモ画面。これにapp://self/performanceというフレームワーク実行パフォーマンスを測定するappリソースがありindexページではpageのGETリクエストに応じてセットしています。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'performance'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">resource</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app://self/performance'</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>page / secで表示されている値がそうです。<br />
<a href="http://www.bear-project.net/blog/wp-content/uploads/2012/04/9bed6295cf4f6d5746d67365cba086de.png"><img src="http://www.bear-project.net/blog/wp-content/uploads/2012/04/9bed6295cf4f6d5746d67365cba086de.png" alt="" title="スクリーンショット 2012-04-25 4.15.17" class="alignnone size-full wp-image-1358" /></a></p>
<p>これはeagerが使われていないので、bodyのperformanceにapp://self/performanceへのGETリクエストがセットされたことになります。このリソースが実際に行われるのはコンパイル済みのテンプレートでこのリソースが出現するタイミングです。</p>
<p>smartyのコンパイル済みテンプレートではこの部分です。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;p&gt;&amp;copy; 2012 &lt;a href=&quot;https://twitter.com/#!/bearsunday&quot;&gt;@BEARSunday&lt;/a&gt; (&lt;?php echo $_smarty_tpl-&gt;tpl_vars['performance']-&gt;value;?&gt;<br />
&lt;/p&gt;</div></div>
<p>ここで初めてリクエストが行われます。パフォーマンスを測定するという目的からすればよページクラスのメソッドで計測するより、テンプレートで表示される直前に計測される値の方がより正確でしょう。またこのパフォーマンスリソースはテンプレートで出現しなければ計測されることもありません。実際に利用されるかされないかを気にしないでページはテンプレートにリクエストをセットすることができます。</p>
<h2>リソースキャッシュ</h2>
<p>パフォーマンスappリソースを使ったページリソースをキャッシュしても、パフォーマンスリソースの値は正しく反映されることに注目してみてください。これはページが保持してるのはリソースリクエストの結果ではなく、リソースリクエストの方法だからです。リクエスト方法はキャッシュされ再利用されても、その値は毎回変わります。</p>
<h2>リソースまとめ</h2>
<ul>
<li>リソースリクエストはリクエストの生成と実行というライフスタイルを持ちます。</li>
<li>リソースはURIから生成され、リソースリクエストを実行するアダプターはURIのスキーマで決まります。</li>
<li>リソースリクエストはURI文字列で表現されます。</li>
<li>リソースリクエストの引き数はネームドパラメーターで渡されます</li>
<li>作成されたリソースリクエストはクロージャのように扱えます</li>
<li>リソースはレンダラーを個別に保持し自身をリソース状態からリソース表現にレンダリングすることができます。</li>
<li>リソース表現は文字列評価することで得られます。</li>
<li>レンダラーの使用はオプションです。なければコンテンツが表現にならないか検討します。</li>
<li>レンダラーはユーザーが記述することができます。</li>
<li>レンダラーはテンプレートエンジンを持ちます。設計上固定化されたものはありませんが、現在のデモではSmarty3が使われています。</li>
</ul>
<p>他にもサービスを通じて一度しか行われないオブジェクトコンストラクション、不足している引き数を補充するパラメータープロバイダー、スキーマアダプターを構成するDSL、リソースの関係性を内部で持つリソースリンク、webブラウザでタブを開くようにリンク先を加えていくnewリンク、リソースリンクをクローリングしてリソースのリンク構造を構成するクローラーリンク、リソースリンクを露出することなくアプリケーション状態を変更するHATEOUS（Hypermedia as the Engine of Application State）等様々な機能がありますがまた別の機会に紹介したいと思います。<sup><a href="http://www.bear-project.net/blog/2012/04/bear-resource/#footnote_4_1178" id="identifier_4_1178" class="footnote-link footnote-identifier-link" title="きっともうお腹一杯でしょう！">5</a></sup></p>
<h2>次回はRay.Di</h2>
<p>次回の記事はDIです。BEAR.SundayはRay.Diというディペンデンシーインジェクターを用いてオブジェクトのコンストラションおよびインジェクションを行います。Ray.DiはBEAR.Sundayのために開発したGoogle GuiceクローンのDIフレームワークです。アノテーションを用いつつサービスコンテナにも依存しないよりクリーンなDIが可能です。</p>
<ol class="footnotes"><li id="footnote_0_1178" class="footnote">HelloWorldしか出ない状態が長く続いたのにも関わらずソースをみたり関心を持ってもらった方がおられました。ありがとうございます</li><li id="footnote_1_1178" class="footnote"><a href="http://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87">シンタックスシュガー</a> </li><li id="footnote_2_1178" class="footnote">一方、pageリソースの役割はリクエストURIに応じて複数のappリソースをアクセスする事がほとんどです。</li><li id="footnote_3_1178" class="footnote">アプリケーションスコープでシングルトン</li><li id="footnote_4_1178" class="footnote">きっともうお腹一杯でしょう！</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/04/bear-resource/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでアノテーション</title>
		<link>http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/</link>
		<comments>http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 16:14:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Annotation]]></category>
		<category><![CDATA[Doctrine Commons]]></category>
		<category><![CDATA[アノテーション]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1148</guid>
		<description><![CDATA[アノテーションとは プログラミングでは、コード中に登場する要素(クラス、メソッドなど)に対して、それ自体に関する情報(メタデータ)を注記できる仕組みのことをアノテーションという。「このメソッドはテスト用である」「ここでコ...  <a href="http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/" class="more-link" title="Read PHPでアノテーション">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>アノテーションとは</h2>
<blockquote><p>プログラミングでは、コード中に登場する要素(クラス、メソッドなど)に対して、それ自体に関する情報(メタデータ)を注記できる仕組みのことをアノテーションという。「このメソッドはテスト用である」「ここでコンパイラは警告を出してはならない」「このメソッドはオーバーライドである」などの情報を付記し、コンパイル時や実行時に参照させることができる。</p></blockquote>
<p style="text-align: right;"><a href="http://e-words.jp/w/E382A2E3838EE38386E383BCE382B7E383A7E383B3.html">IT用語辞典</a></p>
<p>このように説明されるアノテーションですが、その源流を調べてると次の文章に出会いました。</p>
<blockquote><p>アノテーションとは、JDK 1.5で新たに追加される言語仕様であり、Javaコード上でメタデータ（コードそのものではなくコードに関する付加情報）を記述可能にする。これは、マイクロソフトC#における属性（attribute）に相当するシンタックスで、アノテーションはそれを後追いした仕様といえる。</p></blockquote>
<p><a href="http://www.atmarkit.co.jp/fjava/kaisetsu/j2eewatch02/j2eewatch02.html">2004年の@ITnoの記事</a>です。</p>
<p>つまりJavaのアノテーションはC#のアトリビュートに強く影響を受けたものみたいです。<br />
そのことについてC#の作者、<a href="http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%B3%E3%83%80%E3%83%BC%E3%82%B9%E3%83%BB%E3%83%98%E3%83%AB%E3%82%B9%E3%83%90%E3%83%BC%E3%82%B0">アンダース・ヘルスバーグ</a>氏のインタビューが@ITの<a href="http://www.atmarkit.co.jp/fdotnet/insiderseye/20060215cscommunity/cscommunity_01.html">C#への期待。アンダースからの返答</a>という記事の中で見つかりました。</p>
<blockquote><p>■Java言語の進化（例：Annotationなど）についてどのように考えているか？</p>
<p>アノテーション（Annotation）に関しては、.NETの属性（Attribute）のJavaバージョンといえると思うが、このように.NETで実装してきていることを、やはりJavaでも行ってきているという印象だ。実際にJavaの最新バージョン5.0に搭載された新機能の中で、（先ほどのアノテーションも含めて）.NETに触発されて導入されたと思われるものがいくつもある。</p></blockquote>
<p>その.Netの<a href="http://msdn.microsoft.com/ja-jp/library/z0w1kczw.aspx">属性ページ</a>ではこのように説明されています。</p>
<blockquote><p>属性は、プログラムにメタデータを追加します。 メタデータは、プログラム内で定義されている型に関する情報です。 すべての .NET アセンブリに、指定した一連のメタデータが含まれ、そこにはそのアセンブリ内で定義されている型および型のメンバーが記述されています。 カスタム属性を追加すると、必要な任意の追加情報を指定できます。</p>
<p>アセンブリ全体、モジュール全体、クラスやプロパティなどの小さいプログラム要素に、1 つ以上の属性を適用できます。</p>
<p>属性は、メソッドやプロパティの場合と同じ方法で引数を受け取ることができます。</p>
<p>プログラムは、リフレクションを使用することにより、そのプログラム専用のメタデータや他のプログラム内のメタデータを調べることができます。</p></blockquote>
<p>Javaの<a href="http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/language/annotations.html">注釈</a>ではこのように説明されています。</p>
<blockquote><p>注釈はプログラムのセマンティクスに直接影響しませんが、ツールやライブラリがプログラムを扱う方法に影響します。そのため、実行中のプログラムのセマンティクスに影響する場合があります。注釈はソースファイル、クラスファイル、または実行時にリフレクションとして読み取ることができます。</p></blockquote>
<h2>PHPでのアノテーション</h2>
<p>PHPはアノテーションはネイティブサポートさていませんが、&#8221;Status: Under Discussion”のアノテーション提案があります。</p>
<ul>
<li><a href="https://wiki.php.net/rfc/annotations-in-docblock">Annotations in DocBlock</a></li>
</ul>
<p>※<a href="https://wiki.php.net/rfc/annotations">Class Metadata</a>という前の提案は否決されたようです</p>
<p>アノテーションの定義</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> ReflectionAnnotation<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>\stdClass <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>アノテーションの表記</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Foo class.<br />
&nbsp;*<br />
&nbsp;* @Entity {&quot;repositoryClass&quot;: &quot;FooRepository&quot;}<br />
&nbsp;* @Table &nbsp;{&quot;name&quot;: &quot;foos&quot;}<br />
&nbsp;*<br />
&nbsp;* @author &quot;Guilherme Blanco&quot;<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Foo<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>アノテーションの利用</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$reflClass</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> \ReflectionClass<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reflClass</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAnnotations</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>PHPの言語としてのサポートにが無いのにも関わらず、現在多くのライブラリ・フレームワークでアノテーションがサポートされています。なぜアノテーションを必要と考えるのでしょうか？提案者はこのように説明しています。</p>
<blockquote>
<h3><a id="why_do_we_need_class_metadata" name="why_do_we_need_class_metadata">Why do we need Class Metadata?</a></h3>
<div>
<p>Frameworks in general rely on metadata information in order to correctly work. They can use it for many purposes:</p>
<ul>
<li>
<div><strong>phpUnit</strong> Providing  meta functionality for test cases, examples: @dataProvider for test data  iteration, @expectedException for catching exceptions, etc.</div>
</li>
<li>
<div><strong>Doctrine</strong> For Object-Relational mapping, examples: @Entity, @OneToOne, @Id, etc.</div>
</li>
<li>
<div><strong>Zend Framework Server classes</strong> Used to automate mappings for <acronym title="Extensible Markup Language">XML</acronym>-<acronym title="Remote Procedure Call">RPC</acronym>, <acronym title="Simple Object Access Protocol">SOAP</acronym>, etc.</div>
</li>
<li>
<div><strong>FLOW3</strong> for dependency injection and validation</div>
</li>
<li>
<div><strong>Symfony2</strong> for routing rules</div>
</li>
<li>
<div><strong>Others</strong> One clear thing that comes to my mind is Validation, Functional Behavior injection (which could take advantage of <a title="rfc:traits" href="https://wiki.php.net/rfc/traits">Traits</a>), etc. Also, any Framework could take advantage of it somehow.</div>
</li>
</ul>
<p>So, any meta mapping injection could be easily achieved via the implementation of a centralized Annotations support.</p>
<p>The .NET framework uses Data Annotation: <a title="http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs" rel="nofollow" href="http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs">http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs</a></p>
<p>An advantage here is the .net framework will process some annotations and inject behavior into the compiled source code.</p>
</div>
<p>It&#8217;s important to note that annotations exist in java and .net but many  strong use cases exist in these languages to provide hints to the  compiler (@NotNull).</p></blockquote>
<p>他に自分が知ってる範囲では、Java Beanの影響を強く受けた<a href="http://marcelog.github.com/Ding/">DIng</a>やRESTful PHP frameworkの<a href="http://www.recessframework.org/">Recess</a> や<a href="https://github.com/ralphschindler/zf2-di-use-cases/blob/master/09-runtime-setter-injection-with-annotation.php">Zend Framwork2のDi</a>でもアノテーションが使われています。</p>
<p>ネイティブサポートがないという事はPHPでDocCommentの部分<sup><a href="http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/#footnote_0_1148" id="identifier_0_1148" class="footnote-link footnote-identifier-link" title="リフレクションで取得できます">1</a></sup> をPHPでパースしなくてはならなく、速度的にも不利なところがあるのですが、このようにPHPでもフレームワーク・ライブラリを中心に使われるようになってきているようです。デ・ファクトと言えるようなライブラリがないのか、各ライブラリが独自でパースしてるものが多く、GuiceクローンのアノテーションベースのDIコンテナ <a href="https://github.com/koriym/Ray.Di">Ray.Di</a> を実装したときも最初はそうしていました。</p>
<h2>Doctrine\Commons\Annotations</h2>
<p>ORMで有名なDoctrineですが、ORMの他にもプロジェクトがいくつか登録されていてライブラリとしてdoctrine ORM使用しているものを単体使用できるようになっています。<sup><a href="http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/#footnote_1_1148" id="identifier_1_1148" class="footnote-link footnote-identifier-link" title=" (Zend Frameworkのように）このようにライブラリ・ファーストとして部分をライブラリとして単体使用できるのが、最新フレームワークの特徴だと思います">2</a></sup></p>
<p><a href="http://www.doctrine-project.org/projects/common">Docotrine Commons</a>というライブラリがあります。</p>
<blockquote><p>Common</p>
<p>The Doctrine Common project is a library that provides extensions to core PHP functionality.</p></blockquote>
<p>&#8220;PHPの機能を拡張するライブラリです&#8221;という説明で、Doctrineが使っているAutoloaderやCacheもあるのですが、注目は<a href="http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html">Doctrine Annotations</a><sup><a href="http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/#footnote_2_1148" id="identifier_2_1148" class="footnote-link footnote-identifier-link" title=" このドキュメントは2.1のものです ">3</a></sup> です。</p>
<p>RFC提案されてるようにアノテーションを扱います。</p>
<p>アノテーションの定義</p>
<p>@Annotation、@Targetは Doctrineが使用するアノテーションのアノテーションです。<br />
このアノテーションはクラスとメソッドにアノテートすることができます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009933; font-style: italic;">/**<br />
&nbsp;* Inject<br />
&nbsp;*<br />
&nbsp;* @Annotation<br />
&nbsp;* @Target(&quot;CLASS&quot;)<br />
&nbsp;* @Target(&quot;METHOD&quot;)<br />
&nbsp;*<br />
&nbsp;* @package &nbsp; &nbsp;Ray.Di<br />
&nbsp;* @subpackage Annotation<br />
&nbsp;*/</span><br />
final <span style="color: #000000; font-weight: bold;">class</span> Inject implements Annotation<br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>setDbメソッドを@Injectとアノテートしました。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* @Inject<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @param DbInterface $db<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setDb<span style="color: #009900;">&#40;</span>DbInterface <span style="color: #000088;">$db</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>アノテーションの利用</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$reflMethod</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ReflectionMethod<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyCompany\Entity\User'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'setDb'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$methodAnnotations</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$reader</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMethodAnnotations</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reflMethod</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>これで全てのアノテーションが取得できます。<br />
あるいは以下のようにして特定アノテーションの値が取得できます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$methodAnnotation</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$reader</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMethodAnnotation</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reflMethod</span><span style="color: #339933;">,</span> <span style="color: #000088;">$annotation</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Doctrine\Common\Annotations\AnnotationReader が標準的なアノテーションリーダーです。 (Symfony2では標準でサービスコンテナに登録されてるようです)。<br />
他にはそのAnnotationReaderを利用するCachedReader、use文による名前解決を行わない、より簡素な SimpleAnnotationReaderがあります。</p>
<p>またReaderを使わずパースライブラリとして使いたいなら、doc内のアノテーションを行うDoctrine\Common\Annotations\DocParser や PHPスクリプトを解析してのuse文の名前解決を行う Doctrine\Common\Annotations\PhpParser も有用だと思います。use文の名前解決については Symfony2のブログ <a href="http://www.symfony.gr.jp/blog/20110523-symfony2-annotations-gets-better">Symfony2: アノテーションが改善されました</a>も参考になると思います。<sup><a href="http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/#footnote_3_1148" id="identifier_3_1148" class="footnote-link footnote-identifier-link" title=" Fabienさんの記事で、@masakielasticさん翻訳の記事です ">4</a></sup> </p>
<p>※他には<a href="http://code.google.com/p/addendum/">addendum</a> , <a href="http://code.google.com/p/php-annotations/">php-annotations</a>というライブラリもあります。</p>
<h2>Conclusion</h2>
<p>PHPではアノテーションのネイティブサポートはなく、以前は使用はあまり一般的ではありませんでした。しかしPHPUnitでもすっかりおなじみのようにメタプログラミングを実現するためのツールとしてPHP界でも認知されつつあります。自作のライブラリやアプリケーションでも Doctrine Annoattion を用いれば利用の敷居は下がります。速度的な懸念も CachedReaderを使用したり、Configrationに用いたりすることで問題にならない場合も多いでしょう。</p>
<p>ではどのように使うのが良いのでしょうか？広く使われてる割にはなかなかベストプラクティス系の記事が見つかりませんが、１つ見つけました。興味ある方は一読すれば参考になると思います。</p>
<p><a href="http://willcode4beer.com/design.jsp?set=annotations_gotchas_best_practices">Annotations Gotchas and Best Practices<br />
</a></p>
<p>Ray.DiでもこのDoctrine Annotationを採用しリファクタリングを行いました。</p>
<ol class="footnotes"><li id="footnote_0_1148" class="footnote">リフレクションで取得できます</li><li id="footnote_1_1148" class="footnote"> (Zend Frameworkのように）このようにライブラリ・ファーストとして部分をライブラリとして単体使用できるのが、最新フレームワークの特徴だと思います</li><li id="footnote_2_1148" class="footnote"> このドキュメントは2.1のものです </li><li id="footnote_3_1148" class="footnote"> Fabienさんの記事で、@masakielasticさん翻訳の記事です </li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2012/02/php%e3%81%a7%e3%82%a2%e3%83%8e%e3%83%86%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BEAR.Sunday Note</title>
		<link>http://www.bear-project.net/blog/2011/12/bear-sunday-note/</link>
		<comments>http://www.bear-project.net/blog/2011/12/bear-sunday-note/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 15:50:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[PHP Framework]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1121</guid>
		<description><![CDATA[BEAR.Sunday NoteというBEAR.Sundayのスライドを用意しました。 アーキテクチャやアイデアを図や付箋紙でノートのように書いてアップデートしていこうと思います。 BEAR.Sunday Note Vi...  <a href="http://www.bear-project.net/blog/2011/12/bear-sunday-note/" class="more-link" title="Read BEAR.Sunday Note">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>BEAR.Sunday NoteというBEAR.Sundayのスライドを用意しました。<br />
アーキテクチャやアイデアを図や付箋紙でノートのように書いてアップデートしていこうと思います。</p>
<div style="width:595px" id="__ss_10634752"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/akihito.koriyama/bearsunday-tmp-slide" title="BEAR.Sunday Note" target="_blank">BEAR.Sunday Note</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10634752?rel=0" width="595" height="497" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/akihito.koriyama" target="_blank">Akihito Koriyama</a> </div>
</p></div>
<p>体系的でちゃんととしたものではありませんがが、&#8221;アジャイルメモ&#8221;のように使って行く事で、<br />
アイデアや設計がより整理されるかもと考えました。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2011/12/bear-sunday-note/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Dis Is It.</title>
		<link>http://www.bear-project.net/blog/2011/12/php-dis-is-it/</link>
		<comments>http://www.bear-project.net/blog/2011/12/php-dis-is-it/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 14:40:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=1084</guid>
		<description><![CDATA[昨日2011.12.17にPHP Apocalypse というイベントで&#8221;PHP: Dis Is It&#8221;と題した発表をしました。 PHP Disを、そのDisそのものよりDisのありようやDis周...  <a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/" class="more-link" title="Read PHP: Dis Is It.">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>昨日2011.12.17にPHP Apocalypse というイベントで&#8221;PHP: Dis Is It&#8221;と題した発表をしました。<br />
PHP Disを、そのDisそのものよりDisのありようやDis周辺つまり&#8221;Meta  Dis&#8221;視点で考察を行い、PHPという言語のネイチャーを探ろうとしました。</p>
<div style="width:595px" id="__ss_10628706"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/akihito.koriyama/php-dis-is-it-10628706" title="PHP: Dis Is It" target="_blank">PHP: Dis Is It</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10628706" width="595" height="497" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/akihito.koriyama" target="_blank">Akihito Koriyama</a> </div>
</p></div>
<h2>PHPに未来を感じる方いますか？</h2>
<p>「PHPに未来を感じる方いますか？」こういう質問をされた発表者の方がいました。僕は勢いよく&#8230;と言わないまでも挙手したのですが、周囲を見渡してみると自分一人のようでした。その方の発表では「恐らくPHPは緩やかな下降線を辿っていくと、現在ターミナル医療のような状態だ」というような趣旨の発言で、TL見る限りはそれに同意する方も少なくないようでした。<sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_0_1084" id="identifier_0_1084" class="footnote-link footnote-identifier-link" title="つまり自分は少数派だったのですが、同時にだからこそ発表の価値もあるのではと思いました。">1</a></sup>　</p>
<h2>Inconsistency</h2>
<p>inconsistency（一貫性の欠如）という誰もが認めるPHPの欠点をキーワードにその原因を&#8221;混血&#8221;にあるという仮説を立てます。そしてそのInconsistencyを「PHP Disそのもの」にも適用し、本当に言語として駄目設計なら、そのPHP批判にもConsistencyがあるはずなのでは？<sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_1_1084" id="identifier_1_1084" class="footnote-link footnote-identifier-link" title=" 名前空間やクロージャなど誰もが指摘してた欠陥が少なくなってきた現在のPHPなら尚更です ">2</a></sup> そこにConsistencyが無ければどういう理由なのだろうと考察します。</p>
<h2>X Sucks</h2>
<p>ソフトウエアバッシングというのはPHPだけではありません。時代を通じでずっと存在し、あらゆる言語にあり、OSにあり、UNIXにもあります。UNIXはいわば&#8221;Mother of Software&#8221; 過去から今日にいたってあらゆるソフトウエアのファンデーションなのではないか？それを「時代遅れの異臭のするOS」という批判、歴史的で最大の、しかもUNIX制作者によるUNIX批判を紹介しました。そしてその批判の挫折、失敗の考察を紹介し、ではPHPはどうなのかと繋げます。</p>
<h2>最良の者が生き残るのではない</h2>
<blockquote><p>最も強いものが生き残るのではなく、最も賢いものが生き延びるわけでもない。<br />
唯一、生き残るのは変化できるものだけである。
</p></blockquote>
<p>ダーウィンの名著「種の起源」での一節です。PHPは強いアイデンティティを持ちません。<sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_2_1084" id="identifier_2_1084" class="footnote-link footnote-identifier-link" title="カリスマによる強いグランドデザインがありません">3</a></sup> 過去現在に渡って躊躇なく変化してきました。そしてその変化の度に少なからず批判を受けてきたように思います。<sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_3_1084" id="identifier_3_1084" class="footnote-link footnote-identifier-link" title="「だから、PHPにXXXなんか要らないんだって」XXXに色々な言葉がはいってきたように思えます。 ">4</a></sup>　</p>
<p>しかし、その変化し続けるという姿勢が、その変化そのものより重要なのであり、<sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_4_1084" id="identifier_4_1084" class="footnote-link footnote-identifier-link" title="マクルーハンの「メディアはメッセージである」とおなじように ">5</a></sup> 自分はそこに未来を見る。これが僕の「 This Is It」です。このように「Dis Is It」で始まったプレゼンテーションを「This Is It」で結びました。</p>
<h3>Outlook is Gold.</h3>
<p>伝えたかった事はもう一つあります。</p>
<blockquote><p>物事には常に多面性があって自分たちが見ているのは、常にコインのどちらか片方でしかない。
</p></blockquote>
<p>物事を深く広く知れば知るほど、この単純な真実に敬意を示し、反対の立場や考えの異なる人に対する物言いに慎重さや思慮深さが出てくる..ところが現実はそれとは全く反対の方は少なくありません。</p>
<p>「環境に適用しようと変化し続けるものには未来がある可能性が高い」コンピュータ言語の生存をダーウィニズムになぞらえたこの自分の主張も、その多面性のある対象の一考察でしかありません。高名な専門家の、驚くほど一面的でチープな批判を目にした時「これも何かその理由があるんだろう、専門性が視野狭窄に繋がってるのか」そうやって常にその考察背景とアウトルックを問いかけ続ける事ができ、「コインの片側だけで語ってないか？」と疑問を持ち続ける事ができる限り、自分の”self-desciprineランプ&#8221;はグリーンに点灯できてるんじゃないかと思います。エンジニアとして、あるいは問題解決の多面性に対峙する仕事人として、もう少し長く生存できるんじゃないかと考えてます。</p>
<p>「アウトルック にこそ価値がある」&#8230;これがもう一つ伝えたかった事です。 <sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_5_1084" id="identifier_5_1084" class="footnote-link footnote-identifier-link" title="物事の視点、見解">6</a></sup><sup><a href="http://www.bear-project.net/blog/2011/12/php-dis-is-it/#footnote_6_1084" id="identifier_6_1084" class="footnote-link footnote-identifier-link" title="http://lists.sugarlabs.org/archive/iaep/2009-July/006940.html">7</a></sup></p>
<p>自分でタイトルを決めてpublicな場で発表するのはこれが初めてでした。聞いて下さった方、主催関係者の方々、みなさんありがとうございました。</p>
<ol class="footnotes"><li id="footnote_0_1084" class="footnote">つまり自分は少数派だったのですが、同時にだからこそ発表の価値もあるのではと思いました。</li><li id="footnote_1_1084" class="footnote"> 名前空間やクロージャなど誰もが指摘してた欠陥が少なくなってきた現在のPHPなら尚更です </li><li id="footnote_2_1084" class="footnote">カリスマによる強いグランドデザインがありません</li><li id="footnote_3_1084" class="footnote">「だから、PHPにXXXなんか要らないんだって」XXXに色々な言葉がはいってきたように思えます。 </li><li id="footnote_4_1084" class="footnote">マクルーハンの「メディアはメッセージである」とおなじように </li><li id="footnote_5_1084" class="footnote">物事の視点、見解</li><li id="footnote_6_1084" class="footnote">http://lists.sugarlabs.org/archive/iaep/2009-July/006940.html</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2011/12/php-dis-is-it/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>BEAR.Sunday Prototype Preview</title>
		<link>http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/</link>
		<comments>http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 18:30:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BEAR]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Symfony2]]></category>

		<guid isPermaLink="false">http://www.bear-project.net/blog/?p=978</guid>
		<description><![CDATA[BEAR.Sunday Framework dev2 先日、BEAR.Sundayの紹介をSymfony勉強会で行いました。トヨタ車の愛好クラブに出向いてマツダ車の魅力を語るようなもので、またSymfony2というPHP...  <a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/" class="more-link" title="Read BEAR.Sunday Prototype Preview">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>BEAR.Sunday Framework dev2</h1>
<p>先日、BEAR.Sundayの紹介をSymfony勉強会で行いました。トヨタ車の愛好クラブに出向いてマツダ車の魅力を語るようなもので、またSymfony2というPHPのフレームワークの中でも最も成熟したフレームワークを愛好してる方々にHello Worldしか出力できないつくりかけのフレームワークを語るという事でもあり、大変恐縮したのですが成り行きでそういう事になりました。最初は汎用技術だけを話していたのですがこれは面白いかもと思うBEARの一部分も紹介し、一部の方に大変な興味を持ってもらい熱心に聞いていただきました。こちらも刺激とインスピレーションをいただき、整理にもなりました。ここに感謝を持ってそのHello Worldアプリの紹介をしたいと思います。</p>
<p><a href="https://github.com/koriym/BEAR.Sunday">https://github.com/koriym/BEAR.Sunday</a><br />
<a href="https://github.com/koriym/BEAR.Sunday/tree/dev2/apps/00-helloworld-min">https://github.com/koriym/BEAR.Sunday/tree/dev2/apps/00-helloworld-min<br />
</a><br />
(このプロトタイプ作成の目的は全体構成を確認、評価することと、オブジェクトグラフのキャッシュの可否、メソッドインターセプトを利用したリソースオブジェクトのAOP実装、ラフなパフォーマンス評価、ビューとページの構成評価などです。詳しくはGitHubにあります。)</p>
<h2>Hello World</h2>
<p>BEAR.Sundayでは、MVCフレームワークのC=コントローラーにあたる部分をPageリソースが担当します。<br />
最小構成に近いページはこのようになります。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Hello <span style="color: #000000; font-weight: bold;">extends</span> Page<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$code</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">200</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">body</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Hello '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>ページリソースはページコントローラーの役割を持ちます。HTTPをモデルにした、code, headers, bodyの公開されたpublicプロパティを持ちますが、継承元はメソッドを持ちません。またビューオブジェクトも持ちません。代わりにリクエストメソッドに応じたインターフェイスメソッドがあります。ページのGETリクエストに対してonGet()が対応します。</p>
<p>ページの仕事（関心）はテンプレートに何かをセットする事ではなく、自らを構成する事です。最も大事なのはページの状態(code プロパティ）です。デフォルトは200=OKです。それ以外の場合、例えばこのページリソースは$nameを受け取らないとページが構成できないとします。その場合「リクエストに不正がある」400(=Bad Request)をセットします。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">code</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">400</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>たったことだけの事で400 Bad Requestは大げさでしょうか？それはアプリケーションのビューが決めます。表現と構成は別の関心です。例えばそれは「名前を入力して下さい」という画面かもしれませんし、AJAXアクセスに対して400 Bad RequestというHTTPコードと何が足りないかを示すJSONかもしれません。ページはどう表現されるかは関心を持たずに、自らの状態を構成する事だけに専念します。</p>
<h3>ステータスコード</h3>
<p>基本的には以下のような<a href="http://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89">HTTPステータスコード</a>に準じたもので決定します。<sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_0_978" id="identifier_0_978" class="footnote-link footnote-identifier-link" title="アプリケーション状態を表したいが、このHTTPコードに合わない時はUnassignedのところで自分のコードを決め、アサインします。例えば210はログインしてる、211は有料会員の状態等とアプリケーションコードを決めても良いでしょう。">1</a></sup></p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 103-199 &nbsp; Unassigned<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '200' =&gt; 'OK',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '201' =&gt; 'Created',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '202' =&gt; 'Accepted',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '203' =&gt; 'Non-Authoritative Information',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '204' =&gt; 'No Content',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '205' =&gt; 'Reset Content',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '206' =&gt; 'Partial Content',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '207' =&gt; 'Multi-Status',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '208' =&gt; 'Already Reported',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 209-225 &nbsp; Unassigned<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '226' =&gt; 'IM Used',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 227-299 &nbsp; Unassigned<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '300' =&gt; 'Multiple Choices',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '301' =&gt; 'Moved Permanently',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '302' =&gt; 'Found',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '303' =&gt; 'See Other',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '304' =&gt; 'Not Modified',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '305' =&gt; 'Use Proxy',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '307' =&gt; 'Temporary Redirect',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 308-399 &nbsp; Unassigned</div></div>
<p>繰り返しますがこれがどのようなHTTP出力となるかはビューの仕事（関心）です。そのまま出力されるかもしれませんし、2XXは全て200で出力するかもしれません。出力実装の事は考えず、ページはページの事だけを考え自らを構成します。これはプレゼンテーション（ビュー）はページ状態の反映（プロジェクション）でなければならないという考えに基づきます。どのように表現されるかページは最後まで知りません。</p>
<p>リクエストメソッドも同様です。GET, POST以外のリクエストが現状のWebサーバーやHTML4では難しい、とは考えません。別のレイヤーがそのリクエストを担い解決します。ページは純粋な動詞を持ったHTTPが普通に使われる世界にいるように記述します。</p>
<p>この単純な例ではページのコンテンツをbodyプロパティにセットする事で自らを構成しました。code=200でbodyにメッセージの入った単純なページです。</p>
<h2>リソースクライアント</h2>
<p>ページリソースはいわばサービスです。それを利用するクライアント（＝リソースクライアント）がページリソースをアクセスします。このようにサーバーサイドであってもリソースクライアント・リソースサービスは常に区別されます（関心の分離）<sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_1_978" id="identifier_1_978" class="footnote-link footnote-identifier-link" title="MVCで言うとMVCの外側にクライアント（エディター）がいて、外側からコントローラーを操作しているようなものかもしれません。">2</a></sup></p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resource</span><br />
<span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page://self/hello'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">withQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Sunday'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">eager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>リソースをアクセスするのにはこのような専用の表記(<a href="http://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%9B%BA%E6%9C%89%E8%A8%80%E8%AA%9E">DSL</a>)をします。これは「リソースクライアント($resource)を使って、page://self/hello というページリソースを?name=queryというクエリー（問い合わせ）でeager（直ぐに）GETリクエストする」という意味になります。</p>
<p>普通のオブジェクトのメソッドコールと違って、クラス名を使わずURIを使っている点、メソッドコールが名前付引き数（順序でなく変数名で変数を指定している）で行われてる点に注意してみてください。PageリソースはWebサービスを提供しているようにリクエストを受け取とり、自己($this)をレスポンスとして返します。</p>
<p>$responseをvar_dumpしてみます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">object<span style="color: #009900;">&#40;</span>helloWorld\Page\Hello<span style="color: #009900;">&#41;</span><span style="color: #666666; font-style: italic;">#51 (4) {<br />
</span> &nbsp;<span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;uri&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span><br />
&nbsp; string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">17</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;page://self/hello&quot;</span><br />
&nbsp; <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;code&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span><br />
&nbsp; int<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;headers&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span><br />
&nbsp; <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;body&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span><br />
&nbsp; string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Hello Sunday&quot;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>ページリソースが返ってきました。HTTPレスポンスと同じようにcode, header, bodyを持っているのでheader関数とechoで出力するのは容易です。あるいはコンテンツネゴシーエションをして、リクエストヘッダーに応じてJSONやモバイル用コンテンツに出力することもできるでしょう。</p>
<h2>リクエスト</h2>
<p>eagerリクエストは即リクエスト実行です。リクエストの実行結果が取得できます。では、eagerでないリクエストは何が返ってくるのでしょうか？</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resource</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page://self/hello'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">withQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Sunday'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$request</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//get page://self/hello?name=Sunday</span></div></div>
<p>リクエストが返ってきます。このリクエストオブジェクトは文字列表現を持っているので、echoすることができます。リクエストオブジェクトは以下のように関数を実行するように記述すればその時にリクエストが実行されます。</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> &nbsp;<span style="color: #000088;">$request</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>つまり、リソースリクエストはeagerをつけると即実行、つけないといつでも実行可能なリクエストに必要な全ての情報を持っているリクエストオブジェクト、そのどちらかが得られます。 <sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_2_978" id="identifier_2_978" class="footnote-link footnote-identifier-link" title="request()以外の全てのメソッドは$thisが帰って来ててデメテルの法則に従っています">3</a></sup></p>
<h3>REST = Representational State Transfer</h3>
<p>これまで見た来た様に、ページは自らの状態コードとコンテンツをセットして自分自身を構成します。<sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_3_978" id="identifier_3_978" class="footnote-link footnote-identifier-link" title="ただ代入してるのだけに大げさな言い方に聞こえるかも知れませんが">4</a></sup> リソースクライアントからのリクエストを受けてページはその構成された状態を<em>return $this;</em>と返します。RESTはRepresentational State Transferの略です。直訳すると<strong>（リソースの）表現状態の転送</strong> 。BEARのリソースもこの原則に従っています。</p>
<p>この記事での「あいさつページリソース」は「Hello Sunday !」という（リソース）表現状態（Representational State）になってリソースクライアントに転送(Transfer)されます。Representational State Transfer、つまり<a href="http://ja.wikipedia.org/wiki/REST"> REST</a>です。</p>
<h2>テスタビリティ</h2>
<p>リソースはその利用がサーバーサイド内部でもクライアントとサービスに分かれてるので、テストコードではそのクライアントをそのまま記述できます。</p>
<p>ページの仕事はテンプレートのHTMLを構成することではなく、ページ自身を構成することなので、ページがどのような状態なのかページのHTMLを見るまでもなく、まずコードに入っています。次に（今回説明しませんでしたが）ページのヘッダーにはページのメタ情報が入っています。これもコード同様、どのように出力されるかとヘッダーの内容の実際とは関心が分離されます。<sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_4_978" id="identifier_4_978" class="footnote-link footnote-identifier-link" title="現在デバック用にセットされてるメモリ使用量や速度などヘッダー（ページ実行のメタ情報）は実際のprod環境では出力されないでしょう。">5</a></sup> </p>
<p>これらは全てページコントローラーのテスト可能性に繋がります。</p>
<p>テスト時には全ての出力とPHPコンテキスト、webコンテキストをDBに保存して、デバックに役立てる事ができるかもしれません。入力と出力、プログラムのスタートアップと出力＆終了はユーザードメイン（領域）にあり可能です。<sup><a href="http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/#footnote_5_978" id="identifier_5_978" class="footnote-link footnote-identifier-link" title="設定ファイルやコードでその処理を担うクラスを指定するのではなく、直接コーディングします。">6</a></sup></p>
<h3>スクリプト</h3>
<p>現在試験的にこの最も上位の層での処理をPHPスクリプト(includeしただけで実行される素のPHPスクリプト）で行っています。クラスベースの通常のPHPコーディングと違い、機能単位でスクリプトを用意して複数includeする事で全体を構成しようとしています。</p>
<p>例えばページリソースへのリクエストが終わった段階で、リソースリクエストをハンドルするハンドラスクリプトを用意してあれば、内部アプリケーションリソースURIに応じて特定リソースリクエストにACLを適用したり、実行をページ終了後に行う事ができます。（足跡DBの更新を画面表示のあとに行う等）このように、入力、ページリソースリクエスト、リクエスト実行、出力、などの大きな構造をユーザードメインのスクリプトを読み込むことで構成しています。</p>
<p>またスクリプトをリソースとURIと対応させ、他のフレームワークやCMS等と組み合わせる事を可能にします。<br />
例えば、商品の残り個数がapp://self/goods/stock/quantity/?id=100というアプリケーションURIで利用可能だとして、WordPressのウィジェットなどから</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">残り個数は<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'/path/to/goods/stock/quantity/?id=100'</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>です</div></div>
<p>等と呼べたらどうでしょうか。</p>
<p>リソースは一意につけられるURIというIDを持ち、そのリクエストには状態がありません。自らの表現へのリンクを持つ事ができ、上記のような最小限のリクエストを可能にします。副作用のないGETリクエストは何度でも同じ状態を返すはずでキャッシュも機能するでしょう。上記の最小限のクライアント利用を前提にするので、フロントコントローラーやルーターはBEAR.Sundayではオプションになります。</p>
<p>あるいはページコントローラーの無い、テンプレートとアプリケーションリソースだけがあるページはどうでしょうか。DrupalやWordPressのようなCMSの多くはコンテンツ・プルで情報が取得されます。コントローラーがテンプレートにコンテンツをpushするのではなくて、ビュートリガーで情報がPullされます。テンプレートを先に読み込み、テンプレートに出現したアプリケーションリソースがPullされます。 (詳しくは<a href="http://ja.wikipedia.org/wiki/Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF">Webアプリケーションフレームワーク</a>を）</p>
<h3>まとめ</h3>
<p>モデル（アプリケーションリソース）を持たない単純なHelloWorldアプリを見てきました。リソースリクエスト専用問い合わせ言語（DSL)、ページコントローラーのビューへの無関心（ページは出力を構成しようとせず自らを構成しようとする）、ビューはページリソース状態の反映として扱われる、リソースリクエストは記録可能で遅延実行（レイジーエバリュエーション）可能などの特徴がありました。またそれらの実行フローはスクリプトで構成されアプリケーションドメインになっている。入力と出力はフレームワークが行うのではなく、フレームワークのライブラリを使うがユーザードメインで行う、つまり構成は変更できるという事を見てきました。</p>
<p>今回全然触れなかったものに、アノテーションベースのGuiceスタイルのDIコンテナ、メソッドインターセプターによるアスペクト指向プログラミング、リソースリンク、TraitとDIを使ったテンプレートエンジン選択、マルチアプリケーションリソース、ユーザースキーム、HATEOAS = Hypermedia As The Engine Of Application State（アプリケーション状態のエンジンとしてのハイパーメディア）、オブジェクトグラフキャッシュ等があります。これらは実装がある程度進んで来たもので、現時点でもある程度は紹介可能です。</p>
<p>HTTPを通信プロトコルとしてでなく、アプリケーションスタックとして内部、外部ともに使おうという試みでもあるのですが、今回の記事では一部コードの話で触れただけでした。これができて便利、あれを実装するのが一瞬でできる&#8230;という実装の話でなく、設計やコンセプトに興味を持ってもらったので今回の記事はそれに沿ったミニマムなものにしました。</p>
<p>再度お礼を言います。あの時、スクリーンの真ん前で熱心に見て、聞いて、質問してくださった皆さん、どうもありがとうございました。また別の機会でお会いできればと思います。</p>
<ol class="footnotes"><li id="footnote_0_978" class="footnote">アプリケーション状態を表したいが、このHTTPコードに合わない時はUnassignedのところで自分のコードを決め、アサインします。例えば210はログインしてる、211は有料会員の状態等とアプリケーションコードを決めても良いでしょう。</li><li id="footnote_1_978" class="footnote">MVCで言うとMVCの外側にクライアント（エディター）がいて、外側からコントローラーを操作しているようなものかもしれません。</li><li id="footnote_2_978" class="footnote">request()以外の全てのメソッドは$thisが帰って来ててデメテルの法則に従っています</li><li id="footnote_3_978" class="footnote">ただ代入してるのだけに大げさな言い方に聞こえるかも知れませんが</li><li id="footnote_4_978" class="footnote">現在デバック用にセットされてるメモリ使用量や速度などヘッダー（ページ実行のメタ情報）は実際のprod環境では出力されないでしょう。</li><li id="footnote_5_978" class="footnote">設定ファイルやコードでその処理を担うクラスを指定するのではなく、直接コーディングします。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bear-project.net/blog/2011/12/bear-sunday-prototype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

