'

Что несёт нам Zend Framework 2.0?

Понравилась презентация – покажи это...





Слайд 0

Что несёт нам Zend Framework 2.0? Надежда Блинова, веб-программист, Wizartech Георгий Туревич, ведущий веб-программист, Wizartech 27 марта 2010 г. Санкт-Петербург


Слайд 1

Планируемые изменения Изменения в архитектуре Изменения в MVC Изменения в стандартах кодирования Изменения в прочих компонентах


Слайд 2

Пространства имен __invoke() Замыкания Goto Late Static Binding (LSB) И др. Используемые новинки php 5.3


Слайд 3

Унифицированный конструктор Стандартизация массива Options Исключения Контрактное программирование Уменьшение количества синглтонов Создание компонентов общего назначения Новые возможности Php 5.3 в плагинах Автозагрузка Пространства имен goto Изменения в плагинах Изменения в архитектуре


Слайд 4

Изменения в архитектуре Унифицированный конструктор public function setOptions($options) { // ...     foreach ($options as $key => $value) {         $method = 'set' . $key;         if (method_exists($this, $method)) {             $this->$method($value);         }     }     return $this; } Во многих компонентах в методе setOptions часто встречается повторяющийся код:


Слайд 5

Изменения в архитектуре Унифицированный конструктор namespace Zend; // Новый, общий для всех класс Options c методом setOptions  class Options  {      public static function setOptions($object, array $options)      {          if (!is_object($object)) {              return;          }          foreach ($options as $key => $value) {              $method = 'set' . self::_normalizeKey($key);              if (method_exists($object, $method)) {                  $object->$method($value);              }          }      }        public static function setConstructorOptions($object, $options)      {    ...    }        protected static function _normalizeKey($key)      {  ...    }  } 


Слайд 6

Изменения в архитектуре Унифицированный конструктор namespace Zend;  class Options  {      public static function setOptions($object, array $options)      {  ...  }        public static function setConstructorOptions($object, $options)      {             if ($options instanceof Zend_Config) {              $options = $options->toArray();          }          if (is_array($options)) {              self::setOptions($object, $options);          }      }        protected static function _normalizeKey($key)      {          $option = str_replace('_', ' ', strtolower($key));          $option = str_replace(' ', '', ucwords($option));          return $option;      }  } 


Слайд 7

Изменения в архитектуре Унифицированный конструктор use Zend\Options as Options;  class Foo  {      public $bar = '';      public $baz = '';        public function __construct($options = null)      {          Options::setConstructorOptions($this, $options);      }      public function setOptions(array $options)      {          Options::setOptions($this, $options);      }      public function setBar($value)      {          $this->bar = $value;      }        public function setBaz($value)      {          $this->baz = $value;      }  } 


Слайд 8

Изменения в архитектуре Унифицированный конструктор   $foo = new Foo(array('bar' => 'baz'));  echo $foo->bar; // "baz"    $foo->setOptions(array('bar' => 'boo', 'baz' => 'bat'));  echo $foo->bar . $foo->baz; // "boobat" 


Слайд 9

underscore_separated_keys camelCasedKeys UPPERCASEDKEYS lowercasedkeys all_lowercase_underscore_keys Переводим в camelCase: Изменения в архитектуре Стандартизация массива Options str_replace(' ', '', ucwords(str_replace('_', ' ', $value)));


Слайд 10

Изменения в архитектуре Exceptions. Исключения // у каждого компонента должен быть свой интерфейс Exception namespace \Foo\Bar;  interface Exception  {  }    class InvalidArgumentException      extends \InvalidArgumentException      implements Exception  {  }    try {      throw new InvalidArgumentException();  } catch (\Foo\Bar\Exception $e) {  } 


Слайд 11

Design By Contract формальные, точные и верифицируемые интерфейсы Минимальные требования к компонентам будут вынесены в интерфейсы. С интерфейсами будут предложены стандартные реализации Разработчик сможет расширять стандартные и создавать кастомные реализации на основе интерфейса Изменения в архитектуре Контрактное программирование


Слайд 12

Почему стоит отказаться от синглтона: Глобальное состояние усложняет разработку и тестирование Зависимость обычного класса от синглтона не видна в публичном контракте класса Наличие синглтона понижает тестируемость приложения в целом и классов, которые используют синглтон, в частности Изменения в архитектуре Уменьшение количества синглтонов


Слайд 13

Plugins/Helpers/Strategies Decorators Factories Caching Изменения в архитектуре Создание компонентов общего назначения Области дублирующегося кода будут вынесены в отдельные подключаемые файлы


Слайд 14

__invoke() Изменения в архитектуре Новые возможности Php 5.3 в плагинах class Example {   public function __invoke() {     echo "Hello World! \n";   } } $foo = new Example; $foo();


Слайд 15

Closures (Замыкания) Изменения в архитектуре Новые возможности Php 5.3 в плагинах Нотация: function ($var) use ($outerVar1, $outerVar2, ...) {} Пример: function outer($x) //Определение внешней функции {   $y = 2; //Локальная переменная внешней функции   $inner = function ($a) use ($x, $y) //Определение внутренней функции   {       $b = 4; //Локальная переменная внутренней функции       $res = $x + $y + $a + $b;       echo $res; //Результат будет равен 10   };   $inner(3); //Вызов внутренней функции } outer(1);


Слайд 16

Pros: Польза для фреймворка в целом и Zend_Controller и Zend_Search_Lucene в частности Создание отдельного пространства для unit тестирования: \Test\Zend, \Zend\Test, или \ZendTest Cons Глобальное переписывание кода Изменения в архитектуре Пространства имен


Слайд 17

Полезно при работе с конечными автоматами (FSM - Finite State Machine) парсерами синтаксическими / лексическими анализаторами Компоненты: Zend_Controller_Front Zend_Ical Zend_Search_Lucene Zend_Markup … Изменения в архитектуре Использование goto


Слайд 18

Три стандартных типа: Chains (валидаторы, фильтры, декораторы) Helpers (action helpers, view helpers) Adapters (form display groups, subforms и элементы; database adapters; translation adapters и др. ) Изменения в плагинах


Слайд 19

Отсутствие единообразия имен Разнообразие вызовов: Action helpers: direct() View helpers: formSelect() (имя класса) Validators: isValid() Filters: filter() Снижение производительности: PluginLoader производит лишние операции при каждом поиске. Нет единой парадигмы для конструкторов и/или конфигураций адаптеров Нет единой парадигмы для передачи информации фабрикам Изменения в плагинах Проблемы с плагинами


Слайд 20

Использование пространств имен $loader->registerNamespace('My\Validators');  $class = $loader->load('foo'); //My\Validators\Foo  un/registerNamespace() вместо addPrefixPath() class_exists() Использование имен-через-дефис-в-нижнем-регистре $loader->registerNamespace('My\Validators');  $class = $loader->load('foo-bar');  //My\Validators\FooBar Игнорирование нижнего подчеркивания поиском плагинов Изменения в плагинах Рекомендации: именование плагинов


Слайд 21

Предполагается, что хэлперы будут всегда использовать __invoke() Изменения в плагинах Рекомендации: использование __invoke() При необходимости __invoke() должен переадресовывать на другой метод interface Validator  {  public function isValid($value, $context = null);  public function __invoke($value, $context = null);  } class FooValidator implements Validator  {  public function isValid($value, $context = null)  {       // ...  }      public function __invoke($value, $context = null)  {       return $this->isValid($value, $context);  }  }


Слайд 22

Пример использования: Изменения в плагинах Рекомендации: использование __invoke() $validator = new \My\Foo\Validator();  //новый вызов if ($validator($value)) {} //аналогично старому вызову if ($validator->isValid($value)) {}


Слайд 23

Все адаптеры должны реализовывать интерфейс "Configurable". Изменения в плагинах Рекомендации: реализация интерфейса Configurable interface ConfigurableInterface  {  public function setOptions($options);  }  class Adapter implements ConfigurableInterface  {  public function setOptions($options)  {       // ... настраиваем объект ...  }  } 


Слайд 24

Фабрики будут создавать объект адаптера и передавать ему опции. Изменения в плагинах Рекомендации: реализация интерфейса Configurable class ValidatorFactory  {      public static function factory($options)      {          if ($options instance of \Zend\Config) {              $options = $options->toArray();          }           if (!is_array($options)) {              throw new InvalidArgumentException();          }          $adapter = new $options['type'];          $adapter->setOptions($options['params']);          return $adapter;      }  } Фабрики должны иметь связанный с ними загрузчик плагинов и позволять подключать другие загрузчики.


Слайд 25

Цепочки должны расширять один из классов компонента pubsub: Provider FilterChain Построение стандартных цепочек везде, где это доступно, например, в декораторах Расширение цепочек и добавление подклассов к объектам, которые их подключают Цепочки должны вести себя как загрузчики плагинов, либо подключать загрузчики плагинов Изменения в плагинах Рекомендации: цепочки (Chains)


Слайд 26

Model-View-Controller (MVC, «Модель-представление-поведение», «Модель-представление-контроллер») — архитектура программного обеспечения. Шаблон MVC позволяет разделить данные, представление и обработку действий пользователя на три отдельных компонента Модель (Model) Модель предоставляет данные и реагирует на запросы, изменяя свое состояние. Представление (View) Отвечает за отображение информации (пользовательский интерфейс). Поведение (Controller) Интерпретирует данные, введенные пользователем, и информирует модель и представление о необходимости соответствующей реакции. Новая реализация MVC


Слайд 27

Zend_Controller 2.0 Zend_Controller_Router 2.0 Zend_View 2.0 Zend_Session 2.0 Zend_Form 2.0 Новая реализация MVC


Слайд 28

Цели рефакторинга: После всех изменений компонент должен стать: небольшим гибким свободно расширяемым легким в создании и использовании кастомных реализаций Zend_Controller 2.0


Слайд 29

Две методики : конечный автомат (FSM) событийная модель (Event-driven model) Zend_Controller 2.0


Слайд 30

Реализация похожа на dojo pubsub PubSub == Publish/Subscribe, организация взаимодействий по подписке Основные методы: publish() subscribe() Zend_Controller 2.0 Event-driven Model: PubSub


Слайд 31

Zend_Controller 2.0 Event-driven Model: PubSub class TestPubSub {     public function someFunction($message)     {         echo('someFunction: ' .  $message);     }          public function anotherFunction($message)     {         echo('anotherFunction: ' .  $message);     }     } $classObject = new TestPubSub(); $providerObject = new Provider(); $outerFunction = function ($message) {     echo('outerFunction: ' .  $message); }; 


Слайд 32

Zend_Controller 2.0 Event-driven Model: PubSub $someFunctionHandle = $providerObject->subscribe( 'mvc.routing',  $classObject,  'someFunction' ); $anotherFunctionHandle = $providerObject->subscribe( 'mvc.routing',  $classObject,  'anotherFunction' ); $outerFunctionHandle = $providerObject->subscribe( 'mvc.routing',  $outerFunction ); $providerObject->publish('mvc.routing', 'Join the Dark Side!'); $providerObject->publish('mvc.routing', 'We have cookies!'); $providerObject->unsubscribe($someFunctionHandle); echo('--- Производим unsubscribe функции someFunction ---'); $providerObject->publish('mvc.routing', 'Join the Dark Side!'); $providerObject->publish('mvc.routing', 'We have cookies!');


Слайд 33

Zend_Controller 2.0 Event-driven Model: PubSub someFunction: Join the Dark Side! anotherFunction: Join the Dark Side! outerFunction: Join the Dark Side! someFunction:  We have cookies! another Function:  We have cookies! outer Function:  We have cookies! --- Производим unsubscribe функции someFunction --- anotherFunction: Join the Dark Side! outerFunction: Join the Dark Side! another Function:  We have cookies! outer Function:  We have cookies!


Слайд 34

Событийная модель: Определяется 4 состояния: routing, dispatching, response, error Методам передается событие (Event) Методы изменяют состояние события Вызывающий метод проверяет состояние и реагирует на изменение. Zend_Controller 2.0 Event-driven model


Слайд 35

Zend_Controller 2.0 Event-driven model routing:      ...  dispatching:      $pubsub->publishUntil($stateChanged, 'mvc.dispatching.pre', $e);      $pubsub->publishUntil($stateChanged, 'mvc.dispatching', $e);      $pubsub->publishUntil($stateChanged, 'mvc.dispatching.post', $e);      $e->setState('response');   response:      ...  error:      $pubsub->publishUntil($stateChanged, 'mvc.error', $e);  Определяется 4 состояния :


Слайд 36

Zend_Controller 2.0 Event-driven model //$stateChanged – замыкание, проверяющее состояние события dispatching:     $e->markState();     $pubsub->publishUntil($stateChanged, 'mvc.dispatching.pre', $e);     if ($e->isStateChanged()) {         goto switchState;     }     $pubsub->publishUntil($stateChanged, 'mvc.dispatching', $e);     if ($e->isStateChanged()) {         goto switchState;     }     $pubsub->publishUntil($stateChanged, 'mvc.dispatching.post', $e);     if ($e->isStateChanged()) {         goto switchState;     }     $e->setState('response');


Слайд 37

Zend_Controller 2.0 Event-driven model switchState:     switch ($e->getState()) {         case 'routing':             goto routing;         case 'dispatching':             goto dispatching;         case 'response':             goto response;         case 'error':             goto error;         default:             throw new StateException();     }  


Слайд 38

Объект Request Объект Response Объект Renderer Объект Router Объект Dispatcher Action controllers Объект ErrorHandler Zend_Controller 2.0 Дополнительные компоненты


Слайд 39

Плагины фронт контроллера подписываются только на нужные темы Action helper broker может быть встроен в объект Event Объект View станет зависимым от рендерера, который, в свою очередь, подчинен объекту Responce. Остается возможность внедрить собственные реализации Достигается большой выигрыш производительности Zend_Controller 2.0 Последствия


Слайд 40

Сейчас по умолчанию не производится никакой фильтрации приходящих данных Планируется добавить фильтрацию/валидацию по умолчанию для суперглобальных массивов К суперглобальным массивам без фильтрации обращаться через методы getRaw*() Zend_Controller 2.0 Poka Yoke фильтрация


Слайд 41

Передача ошибки поиска action из __call в noRouteAction() Использование оверлоадинга для доступа к action helpers: __call() будет изменен. Zend_Controller 2.0 Список изменений в Action Controller //вызов через HelperBroker     $this->_helper->redirector('index');  //превратится в $this->redirector('index');  //доступ к свойствам $this->_helper->viewRenderer->setNoRender(true);  //станет таким $this->viewRenderer->setNoRender(true); 


Слайд 42

легкость контрактное программирование роутер будет работать с объектами запросов будут исправлены те ошибки, которые сложно исправить без нарушения обратной совместимости Zend_Controller_Router 2.0


Слайд 43

Используется реализация "Horde Routes" Метод getInstance() предполагается удалить getDefault() и getDefaults() могут стать методами интерфейса Метод match() будет принимать только объект Zend\Controller\Request\Http Построение маршрутов через конфиг Цепочки Маршрут Hostname Поддержка кэширования Zend_Controller_Router 2.0 Изменения в маршрутах


Слайд 44

Поиск совпадений по дереву (tree-matching). В дереве ищется только одно совпадение. Достаточно всего раз отыскать имя хоста вместо поиска его для каждого нового маршрута. Zend_Controller_Router 2.0 Chains


Слайд 45

Из объекта HTTP Request будет создаваться уникальный ключ Найденный результат сохранится. Каждый отдельный маршрут будет достаточно найти единожды. Zend_Controller_Router 2.0 Поддержка кэширования


Слайд 46

Проблемы текущей реализации: Одновременная реализация как логики Модели (фильтрация, валидация, метаданные), так и логики Вида (рендеринг, декораторы) Использование объектов формы для валидации Неоднозначная реализация системы декораторов Zend_Form 2.0


Слайд 47

Изменение form*() view helpers так, чтобы они могли принимать элементы или другие объекты Zend_Form Zend_Form 2.0 Рекомендации: рефакторинг view helpers Zend_Form 2.0 $element->setOptions(array(      'size'      => 25,      'maxlength' => 140,      'class'     => 'form-text',  ));  echo $view->formText($element); 


Слайд 48

Работать с декораторами можно, используя метод PubSub filter(): Zend_Form 2.0 Рекомендации: использование PubSub Будут предложены готовые цепочки: // Учитывая, что Zend\Form\DecoratorChain  // наследует Pubsub\FilterChain // и что render() переадресует на filter():  $chain = new Zend\Form\DecoratorChain();  $chain->subscribe('Zend\Form\decorator\Label');  $chain->subscribe('Zend\Form\decorator\ViewHelper');  $chain->subscribe('My\Decorator\Div');  $chain->setView($view);  echo $chain->render($element);  $chain = new Zend\Form\Decorator\DefinitionListChain;  $chain->setView($view);  echo $chain->render($element);


Слайд 49

Использование PubSub как базы для цепочек фильтров и валидаторов позволит их присоединять и отсоединять. Zend_Form 2.0 Рекомендации: использование PubSub $vChain = new Zend\Validator\ValidatorChain();  $vChain->subscribe('Int');  $vChain->subscribe('MinLength', array(3));  $vChain->subscribe('MaxLength', array(20));  // прекращение валидации на первой ошибке подписчика $vChain->breakOnFailure(true);  $element->setValidatorChain($vChain); if ($element->isValid($values)) { … }    $fChain = new Zend\Filter\FilterChain();  $fChain->subscribe('StringTrim');  $element->setFilterChain($fChain);  $newValues = $elemen->filter($values);


Слайд 50

Для полного разделения View и Model нужно доставать цепочки из формы для использования в модели – и наоборот: Zend_Form 2.0 // Извлекаем ранее созданные цепочки фильтров и валидаторов  // всех элементов формы  $filterChain = $form->getFilterChain();    // Присоединяем к модели:   $model->setFilterChain($filterChain);  Рекомендации: работа с цепочками фильтров и валидаторов


Слайд 51

Объектная структура: Zend_Form 2.0 Zend\FilterChain::__set_state(array(      "foo" => Zend\FilterChain\Element::__set_state(array(          'filterChain' => Zend\Filter\FilterChain(array(              '_subscribers => array(                  'StrimTrim',              ),          )),          'validatorChain' => Zend\Filter\ValidatorChain(array(              '_subscribers => array(                  array('Int'),                  array('MinLength', array(3)),                  array('MaxLength', array(25)),              ),          )),      )),  ))  Рекомендации: работа с цепочками фильтров и валидаторов


Слайд 52

Zend_Form 2.0 Будет использоваться так: $chain->isValid($values);  $value = $chain->get($key);  $chain->set($key, $value);  $chain->setAll($values);  $elementChain = $chain->getChain($key);  Рекомендации: работа с цепочками фильтров и валидаторов


Слайд 53

Все классы форм могут определять свойство "metadata", содержащее пары ключ/значение, и набор методов set/get для метаданных Zend_Form 2.0 Рекомендации: разделение между метаданными и поведением $form->setMetadata(array(      'action' => $url,      'method' => 'post',      'id'     => 'registration',  ));    $element->setMetadata(array(      'class'     => 'form-text',      'size'      => 25,      'maxlength' => 140,  ));  $element->setName('foo'); 


Слайд 54

Сейчас все элементы Zend_Form генерируют id. Отмена генерации id решит целый ряд проблем с UI. Перевод можно перенести в слой view. Цепочки View и Decorators будут получать объект Translator. Zend_Form 2.0 Рекомендации: отмена установки id, перевод


Слайд 55

Конфигурация: создание цепочек из конфигурации больше не будет доступно. Метаданные: отдельный контейнер "metadata" может повлечь проблемы с уже существующими конфигурациями. Удаление ID: Удаление генерации id может повлечь за собой проблемы с UI. Эта особенность, возможно, будет конфигурируемой. Zend_Form 2.0 Проблемы обратной совместимости


Слайд 56

В Zend Framework 1.x компонент Zend_Session является труднотестируемым. Планируется: сделать Zend_Session более тестируемым добавить возможность инъекции массива сессии Zend_Session больше не будет синглтоном Zend_Session 2.0


Слайд 57

Планируется: реализация компонента упростится и станет гибче добавятся брокеры для управления фильтрами и хэлперами благодаря изменениям в MVC переменные будут передаваться во view script по токену Zend_View 2.0


Слайд 58

Список других элементов: Zend_Http_Client 2.0 Zend_Soap 2.0 Zend_Mail 2.0 Планируется улучшить, переработать или внести улучшения / исправления багов, требующие BC breaks Подробнее: http://framework.zend.com/wiki/display/ZFDEV2/Home Другие элементы


Слайд 59

GIT ACL не накладывает ограничений. Каждый разработчик сможет создать локальную копию репозитория Требования к пропускной способности и объему хранилища ниже Упрощается разделение на ветки Возможность организовать рабочие процессы, отличающиеся от рабочих процессов SVN GIT вместо Subversion


Слайд 60

Стандарты кодирования Псевдонимы пространств имен use Zend\Pubsub\Provider as Provider; Псевдонимы (alias) назначаются при использовании "use": Шаблоны: Делая псевдонимом последнюю часть пространства имен, можно просто не использовать нотацию "as Something" use \Zend\Filter; // Псевдонимом будет "Filter"  use \Zend\Form\Element; // Псевдонимом будет "Element"  Псевдоним для класса: или использовать имя класса или подставлять суффиксом пространство имен класса // Псевдоним "HelperBroker" use \Zend\Controller\Action\HelperBroker;   // Добавляя суффикс use \Zend\Filter\Int as IntFilter;         


Слайд 61

Абстрактные классы имена абстрактных классов будут предваряться словом "Abstract" : AbstractController, AbstractForm, и т.п. Интерфейсы должны именоваться описательно и достаточно обобщенно не должны конфликтовать должны четко указывать на задачи интерфейса Configurable Adaptable Resource Role Loadable Builder Указания типов должны использовать доступные псевдонимы везде, где возможно если имя класса появляется в области видимости всего раз, ему тоже рекомендуется задать псевдоним Стандарты кодирования


Слайд 62

Надежда Блинова: nadezhda.blinova@wizartech.ru Георгий Туревич: georgy.turevich@wizartech.ru Вопросы?


×

HTML:





Ссылка: