search
LoginSignup
14

More than 5 years have passed since last update.

posted at

updated at

Organization

アプリケーションはオブジェクトグラフ

HelloWorld

第1日目で試したMyvVendor\HelloWorldアプリは最小構成のアプリケーションです。

bearsunday_2014_adv_2.png

実行可能なBEAR.Sundayアプリケーションの最小構成です。PHPファイルが4つあります。

  • Index.php ページリソース
  • AppModule アプリケーションモジュール

  • www/index.php アプリケーションスクリプト

  • App.php アプリケーションクラス

リソースはMVCフレームワークでいうとモデルに近いものですが、ページリソースはwebのページに対応します。アプリケーションモジュールがDIとAOPの設定を持ちオブジェクトの構成を決定します。

アプリケーションの実行に必要なサービスオブジェクトはアプリケーションオブジェクトが保持しているのでスクリプトはそのサービスを使いアプリケーションを実行します。

アプリケーションスクリプト

アプリケーションの実行手順が記述してあります。

<?php

use BEAR\Resource\Request;
use BEAR\Sunday\Extension\Application\AbstractApp;
use BEAR\Sunday\Extension\Application\AppInterface;
use MyVendor\HelloWorld\AppModule;
use Ray\Di\Injector;

require dirname(__DIR__) . '/vendor/autoload.php';

$app = (new Injector(new AppModule))->getInstance(AppInterface::class);
/** @var $app AbstractApp */

$request = $app->router->match($GLOBALS);
try {
    // resource request
    $page = $app->resource
        ->{$request->method}
        ->uri($request->path)
        ->withQuery($request->query)
        ->request();
    /** @var $page Request */

    // representation transfer
    $page()->transfer($app->responder);

} catch (\Exception $e) {
    $code = $e->getCode() ?: 500;
    http_response_code($code);
    echo $code;
    error_log($e);
}

順に見ていきましょう。5つのステップがあります。

1.オートローダーの登録

require dirname(__DIR__) . '/vendor/autoload.php';

composerのオートロードを利用します。

2.アプリケーションインスタンスの生成

$app = (new Injector(new AppModule))->getInstance(AppInterface::class);

アプリケーションは1つの変数に格納されています。BEAR.Sundayアプリケーションは全体を通してDIが利用されるので、実クラス名がほとんど登場しません。全ての依存の束縛を知るのがAppModuleです。インジェクターはそれを利用しアプリケーションクラスからアプリケーションのインスタンスを生成します。

アプリケーションクラス名ですらもここに登場しないのに注目してください。AppInterfaceに束縛されたアプリケーションクラスが使用されます。

基本的なアプリケーションクラスはこのようなものです。

<?php
namespace BEAR\Sunday\Extension\Application;

use BEAR\Resource\ResourceInterface;
use BEAR\Sunday\Extension\Router\RouterInterface;
use BEAR\Sunday\Extension\Transfer\TransferInterface;

class AbstractApp implements AppInterface
{
    /**
     * @var RouterInterface
     */
    public $router;

    /**
     * @var TransferInterface
     */
    public $responder;

    /**
     * @var ResourceInterface
     */
    public $resource;

    /**
     * @param RouterInterface   $router
     * @param TransferInterface $responder
     * @param ResourceInterface $resource
     */
    public function __construct(
        RouterInterface $router,
        TransferInterface $responder,
        ResourceInterface $resource
    ) {
        $this->router = $router;
        $this->responder = $responder;
        $this->resource = $resource;
    }
}

アプリケーションの振舞いはスクリプトで記述するので、このクラスでは記述されてなく単にスクリプトで使用するサービスオブジェクトを3つ保持しているだけです。

クラスは単純ですが、実際に生成されるインスタンスは複雑です。

http://bearsunday.github.io/readme/print_o/app.html
http://bearsunday.github.io/readme/print_o/app_array.html (詳細)

BEAR.Sundayは適切なDIを使ったオブジェクト指向のアプリケーションでもあります。

オブジェクト指向のアプリケーションは相互に関係のある複雑なオブジェクト網を含んでいます。オブジェクトはあるオブジェクトから所有されているか、他のオブジェクト(またはそのリファレンス)を含んでいるか、そのどちらかでお互いに接続されています。このオブジェクト網をオブジェクトグラフと呼びます。

上記のリンクのオブジェクトグラフの中から検索してMyVendor\HelloWorld\Appを探してみてください。3つのオブジェクトに依存しているルートオブジェクトが見つかるでしょう。それがAppInterfaceに束縛されていたアプリケーションクラスのインスタンスです。

明日はその3つのサービスオブジェクトを使ってアプリケーションを実行するところに続きます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
14