Ark::ModelsでMyApp::Modelを(ほぼ)全廃

| コメント(0) | トラックバック(1)

『モダンPerl入門』でも言及されているとおり、MVCのM、つまりモデルについては、ウェブアプリケーションフレームワークとは分離するのが定石です。

で、Arkの場合はこれまで以下のようにArkの管轄外のモジュールに代用させる処理を山のように書いていました。

package Amikeco::Web::Model::User

use Ark 'Model::Adaptor';   # automatically turn on strict & warnings

__PACKAGE__->config(
    class => 'Amikeco::Logic::User',
);

1;
__END__

流石にこれを山のように書くのは辛いので、ラッパークラスでも作ろうかと考えていたのですが、Ark::Modelsの登場により、要はFlyweight的な面倒を見てくれるObject::Containerと仲良くすれば良いと分かったので、MyApp::Model以下のモジュールを殆ど全て消すことが出来ました。

今まで通りに$c->model('Foobar')のような感じで使うために、私は後述するように姑息な手だてを講じていますが、ファイルの数が多くなるよりはましだと思って楽をしてしまいました。委細は以下の通りです。

Amikeco::Web::Models

例によって、この記事では処理やらコメントやらPODやらを省いています。

package Amikeco::Web::Models;

use 5.010_000;

use Any::Moose;

extends qw(
    Ark::Models
);

around 'register' => sub {
    my ($next, $class, $model_name, $model_class) = @_;

    $model_class //= 'Amikeco::Logic::' . $model_name;
    $class->ensure_class_loaded($model_class);

    $class->$next(
        $model_name => sub { $model_class->new },
    );
};

no Any::Moose;

__PACKAGE__->meta->make_immutable;

sub model {
    my ($class, $model_name, $model_class) = @_;

    $class->register($model_name => $model_class);

    return $class->get($model_name);
}

Amikeco::Web::Controller::User

上同。

package Amikeco::Web::Controller::User;

use 5.010_000;
use utf8;

use Exception::Class::TryCatch;

use Amikeco::Web::Models;

use Ark 'Controller';       # automatically turn on strict & warnings

has '+namespace' => (
    default => q{},
);

with qw(
    Amikeco::Auxiliary::Localizable
);

__PACKAGE__->meta->make_immutable;

sub player
    :Chained('/')
    :PathPart('player')
    :CaptureArgs(0)
{
    my ($self, $c) = @_;

    $c->forward('set_environment');
    # $c->stash->{model}{user} = $c->model('User');

    # これでもいいけど
    # Amikeco::Web::Models->register( 'User' );
    # $c->stash->{model}{world} = model('User');

    # 面倒だからこれでいいや、という例
    $c->stash->{model}{world} = Amikeco::Web::Models->model('World');
}

# ...

「ほぼ全廃」の余り

MyApp(この場合はAmikeco::Web)の以下の記述(A::P::A::Credential::Passworddigest_modeや、A::P::A::Store::Data::Modelmodel)は、現状ではMyApp::Model以下と解釈されるので、今はしっかりMyApp::Model::User::Authentication::Digestなどが残っています。MyApp::Modelを完膚無きまでに根こそぎ廃止することが目的ではないので、今は取り敢えずこのままとしています。

package Amikeco::Web;

use Amikeco;

use Ark;                    # automatically turn on strict & warnings

use_plugins qw(
    Authentication
    Authentication::Credential::Password
    Authentication::Store::Data::Model

    Session
    Session::State::Cookie
    Session::Store::Memory
);

conf 'Plugin::Authentication::Credential::Password' => {
    user_field      => 'user_name',
    password_field  => 'password',  # デフォルトと同じ
    password_type   => 'hashed',
    digest_model    => 'User::Authentication::Digest',
};
conf 'Plugin::Authentication::Store::Data::Model' => {
    model           => 'User::Authentication::Store',
    target          => 'user_authentication',
    user_field      => 'user_name',
};

# ...

CGIであればともかく、FastCGIやらServerSimpleやらといった環境では、不要な遅延ローディングになる(当該モデルを始めて使ったときにローディング時間分のペナルティがある)ので、上記は実はあまりいけていないです。

トラックバック(1)

YAPC::Asia 2009で、村瀬(typester)さんのトーク「ark ... 続きを読む

コメントする

筆者"Gardejo"について

  • Twitter: @gardejo
  • GitHub: gardejo
  • CodeRepos: gardejo
  • CPAN: MORIYA

このサイトについて

Eorzea System Worksは、架空のシステム開発結社です。

FF14.name (FinalFantasyXIV.name)では、アヴァター(プレイヤーキャラクター)の管理システムやイベント出欠・リマインダシステムや、リンクシェル(LS)運営・管理システムやDKPシステムなどを設計・開発・公開する予定です。

関連サイト

関連サイトでは、他にもFF14に関連するサイトをいくつか紹介しています。

リンク, トラックバック歓迎

このブログへのリンク(どのページでも構いません)やトラックバックを歓迎します。

設計・開発・運用の参考にさせていただきますので、コメントもお気軽にお寄せください!

個別の記事に対するご意見などのほか、目安箱もご用意しています。

このブログ記事について

このページは、Gardejoが2009年7月17日 01:50に書いたブログ記事です。

ひとつ前のブログ記事は「HTML::Shakan::Renderer::HTMLの派生版(定義リストで描画)」です。

次のブログ記事は「HTML::Shakan::Widgets::Simpleの修正(1) ラジオボタンの関連付け」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

2014年2月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28  

やや真面目なサイト