前回、Mojoliciousを使ってオレオレFW化への道 〜CLI機能の追加〜で、MojoliciousにCLI機能を追加したことを書いたんですが、今回はModelとLogicを分離します。
中規模程度のサイトになってくるとそれなりに処理を共通化させないと自分の頭ではどこに何があるか分からなくなるので、これらは必須です。
現在作成中のサービスでMojoliciousを初めて使っており、今回作成した構造がうまく機能しない可能性もあります。とりあえず、第1弾として実装してみました。また、今回ModelとLogicを分離するのにあたって、Mojoliciousプラグインも一緒に作ってみました。
ディレクトリ構造
lib以下のディレクトリ構造は下記のようになっています。CliとWebでModel, Logicを共通化したかったので、同じ階層に持ってきています。また、分離するのにMojoliciousプラグインとして実装したので、MyApp::Mojolicious::Pluginにプラグインとして置いています。全然大したプラグインではないのと、ほとんど重複しているので1つのプラグインとして実装できると思います。
lib/ ├── MyApp │ ├── Cli │ │ └── Example.pm │ ├── Cli.pm │ ├── Logic │ │ └── Example.pm │ ├── Logic.pm │ ├── Model │ │ └── Example.pm │ ├── Model.pm │ ├── Mojolicious │ │ └── Plugin │ │ ├── Logic.pm │ │ └── Model.pm │ ├── Web │ │ └── Controller │ │ └── Root.pm │ └── Web.pm └── MyApp.pm
MyApp::Mojolicious::Plugin::Model
Logicの方はModelの部分がLogicに変わっただけです。今回アプリを実際に作ってみて共通化して問題なさげだったらModelとLogic用のプラグインを1つにまとめた方が良いかもしれません。
MyApp::Modelとその子クラス
ModelのベースとなるMyApp::Modelとその子クラスになります。まだ、Model共通で使うORMなどは定義していないんですが、ここに定義すればいいのかなと思っています。
プラグインの登録、呼び出し
Mojoliciousプラグインは通常Mojolicious::Pluginから検索するんですが、今回はプロジェクト内にアプリ固有のネームスペース配下にプラグインを設置したのでネームスペースを追加する必要があります。
実際にアプリ内から呼び出してみたところ。無名関数なのでアロー演算子があるが、出来ればコレが無い形で提供できれば呼び出しも綺麗になる。もしくは、こんな感じでも良い。
// コレがベスト my $model = $self->app->model("Example"); // コレでもいい my $model = $self->app->model->load("Example"); |
まぁ、オレオレで使うだけなので、極力文字数が少ない方に越したこと無い。
ということで、とりあえずModelとLogicを分離してみました。