Featured image of post 第8回-ハンドラーを登録しよう - Mooを使ってディスパッチャーを作ってみよう

第8回-ハンドラーを登録しよう - Mooを使ってディスパッチャーを作ってみよう

複数のハンドラーを登録して管理する仕組みを作ります。レジストリパターンを使って、名前でハンドラーを管理する方法を学びましょう。

@nqounetです。

前回は、実行時にハンドラーを動的に切り替える機能を追加しました。

今回は、複数のハンドラーを登録して管理する仕組みを作ります。

問題:ハンドラーが増えると管理が大変

これまでのディスパッチャーでは、ハンドラーを1つずつset_handlerで切り替えていました。しかし、ハンドラーが増えてくると、どこかでハンドラーの一覧を管理したくなります。

例えば「listという名前でListHandlerを、formという名前でFormHandlerを登録しておき、名前を指定するだけで切り替えたい」というニーズが出てきます。

解決策:レジストリでハンドラーを管理する

「レジストリ」とは、オブジェクトを名前付きで登録しておく仕組みです。ハッシュを使って、名前とハンドラーの対応を管理します。

 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
package Dispatcher {
    use Moo;

    has handlers => (
        is      => 'ro',
        default => sub { {} },
    );

    has current_handler => (
        is => 'rw',
    );

    sub register_handler {
        my ($self, $name, $handler) = @_;
        $self->handlers->{$name} = $handler;
    }

    sub dispatch {
        my ($self, $name) = @_;
        my $handler = $self->handlers->{$name};
        if ($handler) {
            $self->current_handler($handler);
            $handler->run;
        } else {
            die "Unknown handler: $name";
        }
    }
};

handlers属性はハッシュリファレンスを持ち、register_handlerメソッドで名前とハンドラーの対応を登録します。

使ってみよう

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# ハンドラーを登録
my $dispatcher = Dispatcher->new;
$dispatcher->register_handler('list', ListHandler->new);
$dispatcher->register_handler('form', FormHandler->new);
$dispatcher->register_handler('thread', ThreadHandler->new);

# 名前を指定してディスパッチ
$dispatcher->dispatch('list');    # 一覧を表示
$dispatcher->dispatch('form');    # フォームを表示
$dispatcher->dispatch('thread');  # スレッドを表示

これで、名前を指定するだけで適切なハンドラーに処理を振り分けられるようになりました。

	flowchart LR
    D[Dispatcher]
    H["handlers = { }"]
    L[ListHandler]
    F[FormHandler]
    T[ThreadHandler]
    
    D --> H
    H -->|"'list'"| L
    H -->|"'form'"| F
    H -->|"'thread'"| T

まとめ

  • 複数のハンドラーを管理するにはレジストリパターンが便利である
  • ハッシュを属性として持ち、名前とハンドラーの対応を管理する
  • register_handlerメソッドでハンドラーを登録する
  • dispatchメソッドで名前を指定してハンドラーを呼び出す

次回予告

次回は、名前からハンドラーを自動で選ぶ仕組みを作ります。ファクトリー的な生成パターンを学びましょう。お楽しみに。

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。