Некоторые фреймворки, такие как Symphony, Laravel, и, конечно же Zend взяли эту технологию на вооружение.
Все это более или менее вписалось в схему MVC. Осталась одна, наверное вечная, дискуссия, какой же должна быть главная брачная пара приложения — Модель и Контроллер?
Одни нам говорят, что Модель должна быть дородной и толстой и при ней стройный и тонкий Контроллер. Одним словом — матриархат.
Другие, наоборот, считают, что Контроллер должен всем управлять и повелевать, поэтому он получается основательный, упитанный. И при нем худенькая, стройненькая Модель, задача которой сводится к подай-принеси. Такой вот патриархат.
Так что же лучше в схеме MVC? Патриархат или матриархат?
Давайте посмотрим на это с точки зрения построения семейной ячейки на основе демократии. И пусть Namespace нам в этом поможет.
Нам не нравятся толстые, неуклюжие Контроллеры, которые, как слон в посудной лавке, по неосторожности могут раздавить все приложение.
Нам не нравятся также толстые Модели. Ну а кому они нравятся? Они должны быть достойны подиума!
Давайте попробуем с помощью Namespace, как с хорошей сватьей, создать гармоничную семью.
Сначала создадим каркас приложения. Как это ни банально, но пусть это будет блог.
Мы создали основну структуру, где:
- Blog — это хранилище нашего приложения;
- Views и Templates — хранилище представлений и шаблонов;
- Utility — хранилище общих библиотек;
- index.php — bootstrap скрипт;
- Post — вот здесь и должна состояться семейная идиллия Контроллера и Модели.
С index.php все просто:
<?php use Blog\Blog as Blog; /* * main application */ define ("APP_PATH", "/home/oleg/www/viper.dev/"); define ("VIEW_PATH", "/home/oleg/www/viper.dev/Blog/Views/"); spl_autoload_register(function ($class) { require_once str_replace('\\', '/', $class). '.php'; }); $blog = new Blog(); $blog->run(); /* * end of index.php */
Определяем нужные пути и создаем автозагрузчик.
Автозагрузчик загружает необходимые классы, которые расположены в иерархии папок согласно пространству имен класса. Например, класс Blog\Post\Services\View будет разыскиваться в Blog/Post/Services.
А вот и первая встреча с Namespace.
При старте index.php мы создаем экземпляр приложения Blog, класс которого загружается из Blog/Blog.php.
Посмотрим на него.
<?php namespace Blog; use Blog\Post\Post as Post; class Blog { public $post; public function __construct() { $this->post = new Post(); } public function run() { $this->post->view->all(); } }//end class Blog
При создании класса Blog мы внедряем в него класс Post с Namespace Blog\Post и автозагрузчик загружает его из Blog/Post/Post.php.
Наверное, этот класс и можно назвать Контроллером,
<?php namespace Blog\Post; use Blog\Post\Services\View as View; class Post { public $view; public function __construct() { $this->view = new View(); } }//end class Post
Сущность Post включает в себя:
— структуру самой записи данных — Blog\Post\Entities\PostEntity.php
<?php namespace Blog\Post\Entities; class PostEntity { public $id; public $title; public $body; }//end class
— службы, обслуживающие запросы Контроллера — Blog\Post\Services\View.php (одна из служб, для примера)
<?php namespace Blog\Post\Services; use Blog\Utility\Contemplate as Contemplate; use Blog\Post\Repositories\Db as DB; class View { public $db; public function __construct() { $this->db = new DB(); }//end __construct public function all() { $posts = $this->db->survey(); Contemplate::compose(array( 'header' => 'header', 'main' => 'main', 'footer' => 'footer', ), array( 'posts' => $posts, 'title' => 'Viper site', )); } }//end class PostView
— систему взаимодействия с базой данных — Blog\Post\Repositories\DB.php — вот она, наша тонкая, изящная Модель,
Только подай-принеси, и ничего больше!
<?php namespace Blog\Post\Repositories; use PDO as PDO; class DB { private $dbh; public function __construct() { $user = 'user'; $pass = 'parole'; try { $this->dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array( PDO::ATTR_PERSISTENT => true )); } catch (PDOException $e) { echo "Error!: " . $e->getMessage() . "<br/>"; die(); } }//end __construct public function survey() { $query_view = $this->dbh->prepare('SELECT * from posts'); $query_view->execute(); return $query_view->fetchAll(PDO::FETCH_CLASS, "Blog\Post\Entities\PostEntity"); }//end survey }//end class Db
В результате нам удалось создать структуру приложения, где все компоненты хорошо связаны, при этом мы добились четкого разделения классов, где каждый класс выполняет свою задачу. Контроллер у нас тонкий и в то же время мощный. Модель под стать ему. Идеальная семья!
И все багодаря Namespace.
Не спорю, во многих случаях удобен фреймворк. Но, посмотрите, Namespace вам ничего не напоминает?
Четкое разделение на классы, строгая, и в тоже время гибкая, полностью подчиненная разработчику иерархия каталогов и классов.
Отсутствие порою такого весомого довеска в виде сотен файлов и классов в виде фреймворка.
Отсутствие прокрустова ложа правил взаимодействия классов и компонентов.
Статья навеяна размышлениями на эту тему Taylor Otwell, автора фреймворка Laravel, за что ему огромное спасибо.
Адрес исходников примера на GitHub: https://github.com/oleg578/PHPNamespaceModel
ссылка на оригинал статьи http://habrahabr.ru/post/178859/
Добавить комментарий