Таблица диспетчеризации (или метод диспетчеризации) - это и таблица (модель), и маршрутизатор / контроллер.
Представьте себе навигацию с вкладками, где может быть 30 вкладок для различных конечных пользователей. Каждая вкладка - это страница, которая имеет свой собственный контроллер и представления. В моем случае таблица отправки содержит ключи для вкладок, а затем данные для каждой вкладки (путь, displayName, видимость и т. Д.).
my $tabs = {
Home => {
action => \&HomeController::dashboard,
displayName => ‘Home’,
...
},
About => {
action => \&AboutController::info,
displayName => ‘About Us’,
...
},
...
};
Изначально у меня были TabController и TabView. Внутри контроллера находилась диспетчерская таблица;однако, похоже, что оно не соответствует MVC. Это было нормально, когда было только 3 вкладки, но отличалось, когда оно росло, особенно потому, что требовалось подрезать безопасность или фильтровать представления.
Имеет смысл перенести его в модель, так как он рассматривается скорее какТаблица данных. Однако, поскольку это Perl (и таблица диспетчеризации), все соответствующие пакеты также должны быть загружены. Таким образом, эта TabModel загружает много контроллеров (и в некоторых случаях представления). Я не особенно люблю загружать / ссылаться на какие-либо контроллеры в модели, поэтому загрузка мульти ощущается еще хуже.
Есть ли передовая практика или пример для этого сценария?
Приложение
В попытке предоставить что-то более осязаемое. Я собираюсь попытаться создать это вокруг временного веб-приложения. Это только концептуальный пример, не полностью работающий и упускающий многое;но, надеюсь, следует добавить немного больше описания и контекста. Он имеет следующую структуру каталогов:
index.pl -- entrance
Controllers/
-- Dashboard.pm
-- Home.pm
-- About.pm
Models/
-- Tabs.pm
-- Users.pm
Views/
-- Dashboard.pm
-- Home.pm
-- About.pm
-- Error.pm
Я не буду разбирать index.pl, но он по сути разбирает параметры и направляет их в DashboardController :: dashboard.
DashboardController
package Controllers::Dashboard;
sub dashboard{
my $users = Models::Users::get_all(); # Users Model
my $tabs = Models::Tabs::get_permitted( # Tabs Model
$users->{CURRENT_USER}{permissions}
);
print Views::Page::render($users,$tabs); # Page View
}
AboutController
package Controllers::About;
sub info {
# No models necessary
print Views::About::render();
}
TabsModel
package Models::Tabs;
use Controllers::Home;
use Controllers::About;
sub get_all {
my $tabs = {
Home => {
action => \&Controllers::Dashboard::dashboard,
displayName => ‘Home’,
...
},
About => {
action => \&Controllers::About::info,
displayName => ‘About Us’,
...
},
...
};
return $tabs;
}
sub get_permitted {
my $user_permissions = shift;
my $tabs = get_all();
if (defined $user_permissions){
foreach my $tab (keys %$tabs){
delete $tabs->{$tab} unless $user_permissions->{"can_access_$tab"};
}
}
}
DashboardView
package Views::Dashboard;
sub render {
my ($users,$tabs) = @_;
my $html_tabs = '<ul>';
foreach my $tab (values %$tabs){
$html_tabs .= "$tab->{displayName}";
}
$html_tabs .= '</ul>;
my $html = <<"END";
$html_tabs
<!-- dashboard content -->
END
return $html;
}