tokuhirom's Blog

Web アプリケーションのロジックを手続きとして実装する話

yusukebe のObject::Containerを応用したModel呼び出し のあたりをよんでの感想ですが。

一時期 Catalyst の影響もあって、モデルのインスタンスつくったりなんだりもしていたのですが、結局のところウェブアプリケーションにおいては、モデルをがんばってオブジェクトにモデリングしようとか考えるよりも、つまり手続として扱った方がしっくりくるな、ということに自分の中でなりまして、最近は、ごちゃごちゃ考えるのをやめて、手続きとして実装しています。

yusukebe の例をベースにはなしをすすめると、コントローラを以下のようにかきます。

package MyApp::Web::Controller::Root;
use Mojo::Base 'Mojolicious::Controller';
use MyApp::M::Entry;

sub index {
    my $self = shift;
    my $entries = MyApp::M::Entry->get_recent_entries();
    $self->stash->{entries} = $entries;
    $self->render();
}

1;

モデルはこんなかんじ。モデルといっても実態は手続きであって、状態はもちません。必要な情報はすべて引数でわたします。 引数は Data::FormValidator をラップしたものでバリデーションされます。

package MyApp::Model::Entry;
use My::Great::Validator;

sub get_recent_entries {
    my $valid = validate(state $r = {
        required => [qw(page rows)],
        defaults => {
            rows => 30,
            page => 1,
        },
    });
    ...;
    return $entries;
}

1;

なぜこういう風にしているかというと、以下のような理由からです。

シャレオツ感は薄いのですが、堅実で、ぼくは好きです。