Что несёт намZend Framework 2.0? презентация

Содержание

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

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

веб-программист, Wizartech

27 марта 2010 г.
Санкт-Петербург


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

прочих компонентах

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


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

возможности Php 5.3 в плагинах
Автозагрузка
Пространства имен
goto
Изменения в плагинах

Изменения в архитектуре


Слайд 5Изменения в архитектуре
Унифицированный конструктор
public function setOptions($options) { // ...
    foreach ($options as $key => $value) {         $method = 'set' . $key;         if (method_exists($this, $method)) {

            $this->$method($value);         }     }     return $this; }

Во многих компонентах в методе setOptions часто встречается повторяющийся код:


Слайд 6Изменения в архитектуре
Унифицированный конструктор
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)      {  ...    }  } 

Слайд 7Изменения в архитектуре
Унифицированный конструктор
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; 
    }  } 

Слайд 8Изменения в архитектуре
Унифицированный конструктор
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;      }  } 

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


Слайд 10underscore_separated_keys
camelCasedKeys
UPPERCASEDKEYS
lowercasedkeys
all_lowercase_underscore_keys


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



Слайд 11Изменения в архитектуре
Exceptions. Исключения
// у каждого компонента должен быть свой интерфейс Exception
namespace \Foo\Bar; 

interface Exception  {  }    class InvalidArgumentException      extends \InvalidArgumentException      implements Exception  {  }    try {      throw new InvalidArgumentException();  } catch (\Foo\Bar\Exception $e) {  } 

Слайд 12Design By Contract
формальные, точные и верифицируемые интерфейсы

Минимальные требования к компонентам будут

вынесены в интерфейсы.
С интерфейсами будут предложены стандартные реализации
Разработчик сможет расширять стандартные и создавать кастомные реализации на основе интерфейса

Изменения в архитектуре

Контрактное программирование


Слайд 13 Почему стоит отказаться от синглтона:

Глобальное состояние усложняет разработку и тестирование

Зависимость

обычного класса от синглтона не видна в публичном контракте класса

Наличие синглтона понижает тестируемость приложения в целом и классов, которые используют синглтон, в частности

Изменения в архитектуре

Уменьшение количества синглтонов


Слайд 14Plugins/Helpers/Strategies

Decorators

Factories

Caching
Изменения в архитектуре
Создание компонентов общего назначения
Области дублирующегося кода будут вынесены в

отдельные подключаемые файлы

Слайд 15__invoke()

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

\n";   } } $foo = new Example; $foo();


Слайд 16Closures (Замыкания)
Изменения в архитектуре
Новые возможности 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);


Слайд 17Pros:
Польза для фреймворка в целом и Zend_Controller и Zend_Search_Lucene в частности
Создание

отдельного пространства для unit тестирования: \Test\Zend, \Zend\Test, или \ZendTest
Cons
Глобальное переписывание кода

Изменения в архитектуре

Пространства имен


Слайд 18Полезно при работе с конечными автоматами (FSM - Finite State Machine)


парсерами
синтаксическими / лексическими анализаторами


Компоненты:
Zend_Controller_Front
Zend_Ical
Zend_Search_Lucene
Zend_Markup



Изменения в архитектуре

Использование goto


Слайд 19 Три стандартных типа:
Chains
(валидаторы, фильтры, декораторы)
Helpers
(action helpers, view helpers)
Adapters
(form display groups,

subforms и элементы; database adapters; translation adapters и др. )

Изменения в плагинах


Слайд 20Отсутствие единообразия имен

Разнообразие вызовов:
Action helpers: direct()
View helpers: formSelect() (имя

класса)
Validators: isValid()
Filters: filter()

Снижение производительности: PluginLoader производит лишние операции при каждом поиске.

Нет единой парадигмы для конструкторов и/или конфигураций адаптеров

Нет единой парадигмы для передачи информации фабрикам

Изменения в плагинах

Проблемы с плагинами


Слайд 21Использование пространств имен
$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

Игнорирование

нижнего подчеркивания поиском плагинов

Изменения в плагинах

Рекомендации: именование плагинов


Слайд 22Предполагается, что хэлперы будут всегда использовать __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);  } 
}


Слайд 23Пример использования:
Изменения в плагинах
Рекомендации: использование __invoke()
$validator = new \My\Foo\Validator(); 

//новый вызов
if ($validator($value)) {}

//аналогично старому

вызову
if ($validator->isValid($value)) {}


Слайд 24Все адаптеры должны реализовывать интерфейс "Configurable".
Изменения в плагинах
Рекомендации: реализация интерфейса Configurable
interface ConfigurableInterface 


{  public function setOptions($options); 


class Adapter implements ConfigurableInterface 
{  public function setOptions($options)  {       // ... настраиваем объект ...  } 


Слайд 25Фабрики будут создавать объект адаптера и передавать ему опции.
Изменения в плагинах
Рекомендации:

реализация интерфейса 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;      }  }

Фабрики должны иметь связанный с ними загрузчик плагинов и позволять подключать другие загрузчики.


Слайд 26Цепочки должны расширять один из классов компонента pubsub:
Provider
FilterChain

Построение стандартных цепочек везде,

где это доступно, например, в декораторах

Расширение цепочек и добавление подклассов к объектам, которые их подключают

Цепочки должны вести себя как загрузчики плагинов, либо подключать загрузчики плагинов

Изменения в плагинах

Рекомендации: цепочки (Chains)


Слайд 27Model-View-Controller
(MVC, «Модель-представление-поведение», «Модель-представление-контроллер») — архитектура программного обеспечения.

Шаблон MVC позволяет разделить

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

Новая реализация MVC


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


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

использовании кастомных реализаций

Zend_Controller 2.0


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


Слайд 31Реализация похожа на dojo pubsub

PubSub == Publish/Subscribe, организация взаимодействий по подписке

Основные

методы:
publish()
subscribe()

Zend_Controller 2.0

Event-driven Model: PubSub


Слайд 32Zend_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); }; 

Слайд 33Zend_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!');

Слайд 34Zend_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!

Слайд 35Событийная модель:

Определяется 4 состояния: routing, dispatching, response, error

Методам передается событие

(Event)

Методы изменяют состояние события

Вызывающий метод проверяет состояние и реагирует на изменение.

Zend_Controller 2.0

Event-driven model


Слайд 36Zend_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 состояния :


Слайд 37Zend_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');

Слайд 38Zend_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();     }  

Слайд 39Объект Request
Объект Response
Объект Renderer
Объект Router
Объект Dispatcher
Action

controllers
Объект ErrorHandler

Zend_Controller 2.0

Дополнительные компоненты


Слайд 40Плагины фронт контроллера подписываются только на нужные темы

Action helper broker может

быть встроен в объект Event

Объект View станет зависимым от рендерера, который, в свою очередь, подчинен объекту Responce.

Остается возможность внедрить собственные реализации

Достигается большой выигрыш производительности

Zend_Controller 2.0

Последствия


Слайд 41Сейчас по умолчанию не производится никакой фильтрации приходящих данных

Планируется добавить фильтрацию/валидацию

по умолчанию для суперглобальных массивов

К суперглобальным массивам без фильтрации обращаться через методы getRaw*()

Zend_Controller 2.0

Poka Yoke фильтрация


Слайд 42Передача ошибки поиска 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); 


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

сложно исправить без нарушения обратной совместимости

Zend_Controller_Router 2.0


Слайд 44Используется реализация "Horde Routes"
Метод getInstance() предполагается удалить
getDefault() и getDefaults() могут стать

методами интерфейса
Метод match() будет принимать только объект Zend\Controller\Request\Http
Построение маршрутов через конфиг
Цепочки
Маршрут Hostname
Поддержка кэширования

Zend_Controller_Router 2.0

Изменения в маршрутах


Слайд 45Поиск совпадений по дереву (tree-matching).

В дереве ищется только одно совпадение.



Достаточно всего раз отыскать имя хоста вместо поиска его для каждого нового маршрута.

Zend_Controller_Router 2.0

Chains


Слайд 46Из объекта HTTP Request будет создаваться уникальный ключ

Найденный результат сохранится.

Каждый

отдельный маршрут будет достаточно найти единожды.

Zend_Controller_Router 2.0

Поддержка кэширования


Слайд 47Проблемы текущей реализации:

Одновременная реализация как логики Модели (фильтрация, валидация, метаданные), так

и логики Вида (рендеринг, декораторы)

Использование объектов формы для валидации

Неоднозначная реализация системы декораторов


Zend_Form 2.0


Слайд 48Изменение 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); 


Слайд 49Работать с декораторами можно, используя метод 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);


Слайд 50Использование 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);


Слайд 51Для полного разделения View и Model нужно доставать цепочки из формы

для использования в модели – и наоборот:

Zend_Form 2.0

// Извлекаем ранее созданные цепочки фильтров и валидаторов 
// всех элементов формы  $filterChain = $form->getFilterChain();    // Присоединяем к модели:   $model->setFilterChain($filterChain); 

Рекомендации: работа с цепочками фильтров и валидаторов


Слайд 52Объектная структура:
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)),              ),          )),      )),  )) 

Рекомендации: работа с цепочками фильтров и валидаторов


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

цепочками фильтров и валидаторов

Слайд 54Все классы форм могут определять свойство "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'); 


Слайд 55Сейчас все элементы Zend_Form генерируют id.
Отмена генерации id решит целый

ряд проблем с UI.


Перевод можно перенести в слой view.
Цепочки View и Decorators будут получать объект Translator.

Zend_Form 2.0

Рекомендации: отмена установки id, перевод


Слайд 56Конфигурация: создание цепочек из конфигурации больше не будет доступно.

Метаданные: отдельный контейнер

"metadata" может повлечь проблемы с уже существующими конфигурациями.

Удаление ID: Удаление генерации id может повлечь за собой проблемы с UI. Эта особенность, возможно, будет конфигурируемой.

Zend_Form 2.0

Проблемы обратной совместимости


Слайд 57В Zend Framework 1.x компонент Zend_Session является труднотестируемым.

Планируется:
сделать Zend_Session более тестируемым
добавить

возможность инъекции массива сессии
Zend_Session больше не будет синглтоном

Zend_Session 2.0


Слайд 58Планируется:
реализация компонента упростится и станет гибче
добавятся брокеры для управления фильтрами и

хэлперами
благодаря изменениям в MVC переменные будут передаваться во view script по токену



Zend_View 2.0


Слайд 59Список других элементов:
Zend_Http_Client 2.0
Zend_Soap 2.0
Zend_Mail 2.0

Планируется улучшить, переработать или внести улучшения

/ исправления багов, требующие BC breaks

Подробнее: http://framework.zend.com/wiki/display/ZFDEV2/Home

Другие элементы


Слайд 60GIT

ACL не накладывает ограничений. Каждый разработчик сможет создать локальную копию репозитория

Требования

к пропускной способности и объему хранилища ниже

Упрощается разделение на ветки

Возможность организовать рабочие процессы, отличающиеся от рабочих процессов SVN

GIT вместо Subversion


Слайд 61Стандарты кодирования
Псевдонимы пространств имен
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;         


Слайд 62
Абстрактные классы
имена абстрактных классов будут предваряться словом "Abstract" : AbstractController, AbstractForm,

и т.п.

Интерфейсы
должны именоваться описательно и достаточно обобщенно
не должны конфликтовать
должны четко указывать на задачи интерфейса
Configurable
Adaptable
Resource
Role
Loadable
Builder

Указания типов
должны использовать доступные псевдонимы везде, где возможно
если имя класса появляется в области видимости всего раз, ему тоже рекомендуется задать псевдоним

Стандарты кодирования


Слайд 63Надежда Блинова: nadezhda.blinova@wizartech.ru
Георгий Туревич: georgy.turevichГеоргий Туревич: georgy.turevich@wizartech.ru

Вопросы?


Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика