Тестовое задание по Laravel

16.10.2017:

Читаю «Разобраться с основами git и git-flow»

  • зачем нужны ветки ? (для возможности работы с отдельным частями проекта)
  • какие бывают ветки ? (master: по-умолчанию, develop и другие вспомогательные ветки)
  • зачем нужен .gitignore ? (для исключения из git’а файлов и папок, чтобы исключить конфликты при слиянии веток)
  • какие проблемы за нас решает git-flow и почему стоит его использовать ? (git-flow автоматизирует процесс управления версиями и приводит систему к общепринятой модели управления версиями)
  • что будет если не писать сообщения к комитам ? (тяжело будет разобраться в каком состоянии находится проект и какие правки были введены)

Читаю о тестировании

  • unit testing (необходимо для тестирования отдельных модулей системы, как-правило это какие-то классы или объединенные участки кода имеющие общую цель)
  • feature testing (необходимо для тестирования ключевых изменений в приложении)
  • regression testing (необходимо для тестирования функциональности системы после изменений в окружающей среде или в самом приложении)
  • integration testing (необходимо для проверки взаимодействия между компонентами или различными частями системы)

Читаю о DRY, KISS, SOLID, YAGNI

  • DRY — «не повторяйся!»
  • KISS — «не усложняй!»
  • SOLID — использовать совокупность принципов написания кода (единственная обязанность, принцип открытости/закрытости, принцип подстановки, принцип разделения интерфейса, принцип инверсии зависимостей)
  • YAGNI — не должно быть избыточного функционала

Читаю о стандартах кодирования

  • Константы писать капсом через нижнее подчеркивание
  • Длина строки не более 120 символов
  • Файлы php не дожны закрываться через — «?>»
  • В одной строке не должно быть более одного выражения
  • В конце непустых строк не одлжно быть пробелов
  • Отступ через 4 пробела
  • Ключевые слова true/false/null писать в нижнем регистре
  • Ключевые слова abstract и final, в случае их наличия, должны располагаться перед указанием области видимости
  • Ключевое слово static, в случае его наличия, дожно располагаться после указания области видимости

Разбираюсь с composer

  • require и require-dev необходимы для добавления зависимостей в composer.json
  • autoload необходим для автозагрузки (классов, пространства имен и файлов)

17.10.2017:

Разбираюсь как работать с gitflow

  • установка в проект: $ git clone —recursive git://github.com/nvie/gitflow.git
  • инциализация gitflow: $ git flow init
  • создание ветки для работы с проектом: $ git flow feature start
  • создание ветки релиза: $ git flow release start
  • для выхода из файла с сообщением использовать комбинацию :wq
  • создание ветки hotfix’а: $ git flow hotfix start
  • справка по gitflow: $ git flow help
  • пример работы с gitflow: https://github.com/deuterium7/package

Читаю о тестировании проекта

  • В Laravel встроена поддержка PHPUnit
  • Создать тест можно с помощью команды: php artisan make:test
  • Тестировать приложение можно отключив посредников:
<?php
  use Illuminate\Foundation\Testing\WithoutMiddleware;
  use Illuminate\Foundation\Testing\DatabaseTransactions;

  class ExampleTest extends TestCase
  {
    use WithoutMiddleware;
    // some code
  }

Локализация проекта

  • Языки интерфейса лежать в папке resources/lang
  • Изменить язык можно в config/app.php
  • Языковые пакеты можно выкачать тут: https://github.com/caouecs/Laravel-lang

18.10.2017:

Middleware

Policies

Events

Notifications

Mails

Api resources

Model factories

Seeds

Resource controllers

Caching

Queues

20.10.2017:

Сделал тестовый пакет через композер

Шаблон проектирования Singleton

  • Необходим для доступа к существующей ООП библиотеке
  • Когда необходима гарантия существования одного объекта класс
  • Пример простой реализации
class Singleton
{
  private $instance; // хранит объект класса
  
  private function __construct()
  {
  }
  
  public static function get()
  {
    if ($this->instance === null)
    {
      $this->instance = new self();
    }
    
    return $this->instance;
  }
}
  • Совокупность одиночек образуют другой шаблон проектирования: сервис-контейнер (multione container)

23.10.2017:

Установка phpunit

Обновленный пакет

Mockery

  • Иструмент тестирования, испольемый вместе с phpunit для создания объектов-заглушек
  • Используя объекты заглушки можно проследить за поведением данных объектов (полезно для последующих реализаций объектов)
  • Документация по Mockery: http://docs.mockery.io/en/latest/
  • Интеграция с PHPUnit: http://docs.mockery.io/en/latest/reference/phpunit_integration.html

Redis

  • БД, используемая для хранения данных, которые не страшно потерять (один из минусов редис — низкая надежность)
  • Redis хранит данные оперативной памяти вида: ключ-значение
  • Структуры данных в редис:
  1. Строки
set users:leto "{name: leto, planet: dune, likes: [spice]}"
  1. Хеши
hset bug:12339 severity 3
hset bug:12339 priority 1
hset bug:12339 details "{id: 12339, ....}"
  1. Списки
rpush newusers goku
ltrim newusers 0 50
  1. Множества
sadd friends:leto ghanima paul chani jessica
sadd friends:duncan paul jessica alia
  1. Упорядоченный множества
zadd friends:leto 100 ghanima 95 paul 95 chani 75 jessica 1 vladimir

24.10.2017:

Шаблон проектирования Dependency Injection (инъекция зависимости)

  • Необходим для:
  1. Автоматической инъекции зависимостей в класс
  2. Создания глобальной конфигурации проекта
  • Плюсы:
  1. Удобная конфигурация всего проекта в одном месте
  2. Гибкость и низкая связанность кода (реализцаия принципа GRASP «Low coupling» — слпбое зацепление)
  3. Удобное unit-тестирование
  • Минусы: делает код более сложным для восприятия;
  • Пример простой реализации
class DI
{
  private $container;
  
  public function get($key)
  {
    if (! array_key_exists($key, $this->container))
    {
      $this->container[$name] = create_element($key);
    }
    
    return $this->container[$key];
  }
}

Шаблон проектирования Observer (наблюдатель)

  • Наблюдатель определяет отношение «один-ко-многим» между объектами
  • Когда состояние одного объекта изменяется, все зависимые объекты получают оповещания
  • Необходим для наблюдения за динамикой объектов
  • Делится на обозревателей и обозреваемого объекта
  • В агрегирующем шаблоне MVC, V — это observer
  • Observer ничего не знает об объекте, который он обозревает, но получает из этого объекта информацию
  • Обозреваемый объект должен знать какой именно объект за ним наблюдает, чтобы вызвать его метод обрабатывающий событие обозреваемого объекта
  • Плюсы: количество наблюдателей за обозреваемым объектом ниограниченно
  • Минусы: каждый объект-обозреватель нужно добавлять явно в обозреваемый объект

Общее о паттернах

  • Паттерн — решение задачи в контексте (в типичной ситуации, в которой применяется паттерн)
  • Задачи паттернов:
  1. Порождающих — организация процесса создания объектов
  2. Структурных — сопоставление правильно организованных структур из объектов и классов
  3. Поведенческих — организация устойчивого взаимодейтсвия между классами или объектами, через правильное формирование информационных потоков
  • Уровни паттернов:
  1. Классов, описывает отношения между классами и их подклассами
  2. Объектов, описывает взаимодействие между объектами
  • Более детально про паттерны проектирования можно прочесть в книге: «Паттерны проектирования» Эрик Фримен

Шаблон проектирования Decorator (декоратор)

  • Динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области рассширения функциональности
  • Типы декораторов соответствуют типам декодируемых компонентов (соответствие достигается посредством следования или реализации интерфейса)
  • Компонент может декорироваться любым количеством декораторов
  • Декораторы обычно прозрачны для клиентов компонента (если клиентский код не зависит от конкретного типа компонента)

Патерн Фабричный Метод

  • Определяет интерфейс создания объекта, но позволяет субклассам выбрать класс создаваемого экземпляра. Таким образом фабричный метод делегирует операцию создания экземпляра субклассам
  • Фабричный Метод основан на наследовании: создание объектов делегируется субклассами, реализующим фабричный метод для создания объектов
  • Задача Фабричного метода — перемещение создания экземпляров в субклассы

Паттерн Абстрактная Фабрика

  • Предоставляет интерфейс создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов
  • Абстрактная Фабрика основана на композиции: создание объектов реализуется в методе, доступ к которому осуществляется через интерфейс фабрики
  • Задача Абстрактной Фабрики — создание семейств взаимосвязанных объектов без зависимости от их конкретных классов

Паттерн Command (Команда)

  • Инкапсулирует запрос в виде объекта, делая возможной параметризацию клиентских объектов с другими запросами, организацию очереди или регистрацию запросов, а также поддержку отмены операций
  • Паттерн Команда отделяет объект, выдающий запросы, от объекта, который умеет эти запросы выполнять
  • Объект команды инкапсулирует получателя с операцией (или набором операций)
  • Инициатор вызывает метод execute() объекта команды, что приводит к выполнению соответствующих операций с получателем
  • Возможна парметризация инициаторов командами
  • Команды могут поддерживать механизм отмены, восстанавливающий объект в состоянии до последнего вызова метода execute()
  • Команды также могут использоваться для реализации систем регистрации команд и поддержки транзакций

Паттерн Адаптер

  • Преобразует интерфейс класса к другому интерфейсу, на которыый расчитан клиент.
  • Адаптер обеспечивает совместную работу классов, невозможную в обычных условиях из-за несовместимости интерфейсов
  • Пользоваться когда необходимо использовать существующий класс с неподходящим интерфейсом
  • Адаптер приводит интерфейс к тому виду, на который рассчитан клиент
  • Объем по реализации адаптера зависит от размера и сложности целевого интерфейса
  • Существуют две разновидности адаптеров: адаптеры объектов и адаптеры классов. Для адаптеров классов необходимо множественное наследование

Паттерн Фасад

  • Представляет унифицированный интерфейс к группе подсистемы.
  • Фасад определяет высокоуровневый интерфейс, упрощающий работу с подсистемой
  • Пользоваться когда необходимо использовать упростить большой интерфейс или семейство сложных интерфейсов
  • Фасад изолирует клиента от сложной подсистемы
  • Для подсистемы можно реализовать несколько фасадов
  • Реализация фасада основана на композиции и делегировании

Паттерн Шаблонный Метод

  • Задает «скелет» алгоритма в методе, оставляя определение реализации некоторых шагов субклассами. Субклассы могут переопределять части алгоритма без изменения его структуры
  • Абстрактный класс Шаблонного Метода может определять конкретные методы, абстрактные методы и перехватчики
  • Абстрактные методы реализуются субклассами
  • Перехватчики не делают ничего или определяют поведение по-умолчанию в абстрактном классе, но могут переопределяться в субклассах
  • Чтобы субкласс не мог изменить алгоритм в Шаблонном Методе, объявите последний с ключевым словом final
  • Паттерны Стратегия и Шаблонный Метод инкапсулируют алгоритмы; один использует наследование, а другой — композицию
  • Фабричный метод является специализированной версией Шаблонного Метода

Паттерн Итератор

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

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

  • Объединяет объекты в древовидные структуры для представления иерархий «часть/целое».
  • Компоновщик позволяет клиенту выполнять однородные операции с отдельными объектами и их совокупностями
  • В реализации паттерна Компоновщик приходится искать баланс между прозрачностью, безопасностью и потребностями

Паттерн Состояние

  • Состояние управляет изменением поведения объекта при изменении его внутреннего состояния. Внешне это выглядит так, словно объект меняет свой класс
  • Паттерн Состояние позволяет объекту иметь много разных вариантов поведения в зависимости от его внутреннего состояния
  • В отличии от процедурных конечных автоматов, состояние в этом паттерне представляется полноценным классом
  • Поведение контекста реализуется делегированием выполняемых операций текущему объекту состояния, с которым он связан посредством композиции
  • Инкапсуляция состояния в классе локализует его возможные изменения
  • Паттерны Состояние и Стратегия имеют похожие диаграммы классов, но решают разные задачи
  • Переходами между состояниями могут управлять как классы состяоний, так и классы контекстов
  • Применение паттерна Состояние обычно увеличивает количество классов в архитектуре
  • Классы состояний могут совместно использоваться несколькими экземплярами контекстов

Паттерн Заместитель

  • Предоставляет суррогатный объект, управляющий доступом к другому к объекту
  • Удаленный заместитель управляет взаимодействием клиента с удаленным объектом
  • Виртуальный заметситель упраляет доступом к объекту, создание которого сопряжено с большими затратами
  • Защитный заместитель управляет доступом к методам объекта в зависимости от привилегий вызывающей стороны
  • На структурном уровне паттерны Заместитель и Декоратор похожи, но они различаются по своим целям
  • Паттерн Декоратор расширяет поведение объекта, а Заместитель управляет доступом
  • Заместители, как и любые «обертки», увелеичивают количество классов и объектов в архитектуре

MVC с точки зрения паттернов

  • Модель реализует паттерн Наблюдатель для оповещения заинтересованных объектов об изменениях состояния. Паттерн Наблюдатель обеспечивает полную независимость модели от представлений и контроллеров. Он позволяет использовать разные представления с одной моделью, или даже несколько представлений одновременно
  • Представление и контроллер реализуют классический паттерн Стратегия. Представление — объект со сменной стратегией, контроллер эту стратегию предоставляет. Представление интересует только визуальные аспекты приложения, а все решения относительно поведения интерфейса делегируются контроллеру. Применение паттерна Стратегия также сохраняет логическую изоляцию представления от модели, потому что все взаимодействия с моделью для выполнения пользовательских запросов осуществляются контроллером. Представлению о них ничего неизвестно.
  • Совместная работа паттернов обеспечивает слабую связанность всех трех компонентов модели MVC, благодаря чему архитектура сохраняет гибкость и четкость

25.10.2017:

Обновленный пакет

Простой QueryBuilder на основе примера по Fluent Interface (Текучий Интерфейс):

26.10.2017:

Абстрактная фабрика (Abstract Factory)

  • Позволяет создавать целые группы взаимосвязанных объектов, которые, будучи созданными одной фабрикой, реализуют общее поведение.
  • Использовать когда необходимо создать семейства или группы взаимосвязанных объектов исключая возможность одновременного использования объектов из разных этих наборов в одном контексте.
  • Пример: https://github.com/deuterium7/abstract-factory-test

Строитель (Builder)

  • Используется для отделения процесса конструирования сложного объекта от его представления, так что в результате одного и того же конструирования могут получаться различные объекты.
  • Дает более тонкий контроль над процессом конструирования, чем другие порождающие паттерны.
  • Пример: https://github.com/deuterium7/builder-test

Фабричный Метод (Factory Method)

  • Шаблон делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.
  • Используется для создания объектов различных типов одним интерфейсом.
  • Пример: https://github.com/deuterium7/factory-method-test

Объектный пул (Pool)

  • Предоставляет набор заранее инициализированных объектов, готовых к использованию («пул»), что не требует каждый раз создавать и уничтожать их.
  • Хранение объектов в пуле может заметно повысить производительность в ситуациях, когда стоимость инициализации экземпляра класса высока, скорость экземпляра класса высока, а количество одновременно используемых экземпляров в любой момент времени является низкой.
  • Пример: https://github.com/deuterium7/pool-test

27.10.2017:

Прототип (Prototype)

  • Помогает избежать затрат на создание объектов стандартным способом (new Foo()), а вместо этого создаёт прототип и затем клонирует его.
  • Позволяет избежать дополнительных усилий по созданию объекта стандартным путем (имеется в виду использованиеключевого слова ‘new’, когда вызывается конструктор не только самого объекта, но и конструкторы всейиерархии предков объекта), когда это непозволительно дорого для приложения.
  • Использовать, когда система не должна зависеть от того, как в ней создаются, компонуются и представляются продукты.
  • Пример: https://github.com/deuterium7/prototype-test

Простая фабрика (Simple Factory)

  • Предоставляет интерфейсы для создания объектов, скрывая саму логику создания от клиента.
  • Использовать когда создание объекта подразумевает какую-то логику, а не просто несколько присваиваний.
  • Пример: https://github.com/deuterium7/simple-factory-test

Одиночка (Singleton)

  • Позволяет содержать только один экземпляр объекта в приложении, которое будет обрабатывать все обращения, запрещая создавать новый экземпляр.
  • Применять с осторожностью, потому что «Одиночка» вносит в приложение глобальное состояние, так что изменение в одном месте может повлиять на все остальные случаи использования.
  • Пример: https://github.com/deuterium7/singleton-test

Пул одиночек (Multiton)

  • Похож на паттерн проектирования Одиночка (англ. Singleton), но в отличае отнего позволяет создавать коллекции экземпляров класса и позволяет получать доступ по ключу.
  • Иногда этот паттерн называют Реестр одиночек.
  • Также как и Одиночку следует применять с осторожностью.
  • Пример: https://github.com/deuterium7/multiton-test

Статическая фабрика (Static Factory)

  • Используется для создания ряда связанных или зависимых объектов.
  • Разница между этим шаблоном и Абстрактной Фабрикой заключается в том, что Статическая Фабрика использует только один статический метод, чтобы создать все допустимые типы объектов.
  • Этот метод, обычно, называется factory или build.
  • Пример: https://github.com/deuterium7/static-factory-test

Адаптер (Adapter)

  • Позволяет использовать интерфейс существующего класса как другой интерфейс.
  • Часто применяется для обеспечения работы одних классов с другими без изменения их исходного кода.
  • Пример: https://github.com/deuterium7/adapter-test

Мост (Bridge)

Компоновщик (Composite)

  • «Компоновщик» описывает общий порядок обработки группы объектов, словно это одиночный экземпляр объекта.
  • Шаблон позволяет клиентам одинаково обращаться к отдельным объектам и к группам объектов.
  • Пример: https://github.com/deuterium7/composite-test

Преобразователь данных (Data Mapper)*

Декоратор (Decorator)

  • Позволяет подключать к объекту дополнительное поведение (статически или динамически), не влияя на поведение других объектов того же класса.
  • Пример: https://github.com/deuterium7/decorator-test

30.10.2017:

Внедрение зависимостей (Dependency Injection)

  • Процесс предоставления внешней зависимости программному компоненту.
  • В полном соответствии с принципом единственной ответственности объект отдаёт заботу о построении требуемых ему зависимостей внешнему, специально предназначенному для этого общему механизму.
  • Необходим для реализации слабосвязанной архитектуры. Чтобы получить более тестируемый, сопровождаемый и расширяемый код.
  • Пример: https://github.com/deuterium7/dependency-injection-test

Фасад (Facade)

  • Объект, предоставляющий упрощённый интерфейс для более крупного тела кода, например библиотеки классов.
  • Разбиение на подсистемы сложной системы позволяет упростить процесс проектирования, а также помогает максимально снизить зависимости одной подсистемы от другой. Однако это приводит к тому, что использовать такие подсистемы вместе становиться довольно сложно. Один из способов решения этой проблемы является ввод паттерна фасад.
  • Главная цель шаблона состоит в уменьшении связности кода и соблюдении Закона Деметры.
  • Пример: https://github.com/deuterium7/facade-test

Текучий Интерфейс (Fluent Interface)

  • Способ реализации объектно-ориентированного API, нацеленный на повышение читабельности исходного кода программы.
  • Текучий интерфейс хорош тем, что упрощается множественный вызов методов одного объекта. Обычно это реализуется использованием цепочки методов, передающих контекст вызова следующему звену.
  • Пример: https://github.com/deuterium7/query-builder-test

Приспособленец (Flyweight)

  • «Приспособленец» — это объект, минимизирующий использование памяти за счёт общего с другими, такими же объектами использования как можно большего объёма данных.
  • Паттерн приспособленец позволяет повторно использовать мелкие объекты в различном контексте.
  • Для уменьшения использования памяти Приспособленец разделяет как можно больше памяти между аналогичными объектами. Это необходимо, когда используется большое количество объектов, состояние которых не сильно отличается.
  • Пример: https://github.com/deuterium7/flyweight-test

Заместитель (Proxy)

  • Это оболочка или объект-агент, вызываемый клиентом для получения доступа к другому, «настоящему» объекту.
  • «Заместитель» может просто переадресовывать запросы настоящему объекту, а может предоставлять дополнительную логику: кеширование данных при интенсивном выполнении операций или потреблении ресурсов настоящим объектом; проверка предварительных условий (preconditions) до вызова выполнения операций настоящим объектом.
  • Наиболее частым применением паттерна прокси является ленивая загрузка (lazy load). «Тяжелые» объекты не всегда разумно загружать в момент инициализации. Более правильным решением будет загрузить его по первому требованию.
  • Пример: https://github.com/deuterium7/proxy-test

Реестр (Registry)*

  • Необходим для создания глобального хранилища.
  • Подобно Одиночке, паттерн Registry вводит объект в глобальную область видимости, позволяя использовать его на любом уровне приложения.
  • Применять с осторожностью, т.к. вносит в приложение глобальное состояние, так что изменение в одном месте может повлиять на все остальные случаи использования.
  • Пример: https://github.com/deuterium7/registry-test

Цепочка ответственности (Chain Of Responsibilities)

  • Содержит исходный управляющий объект и ряд обрабатывающих объектов. Каждый обрабатывающий объект содержит логику, определяющую типы командных объектов, которые он может обрабатывать, а остальные передаются по цепочке следующему обрабатывающему объекту.
  • Аналогия: Допустим, для вашего банковского счёта доступны три способа оплаты (A, B и C). Каждый подразумевает разные доступные суммы денег: A — 100 долларов, B — 300, C — 1000. Приоритетность способов при оплате: А, затем В, затем С. Вы пытаетесь купить что-то за 210 долларов. На основании «цепочки ответственности» система попытается оплатить способом А. Если денег хватает — то оплата проходит, а цепочка прерывается. Если денег не хватает — то система переходит к способу В, и т. д.
  • Пример: https://github.com/deuterium7/chain-of-responsibilities-test

Команда (Command)

  • Объект используется для инкапсуляции всей информации, необходимой для выполнения действия либо для его инициирования позднее. Информация включает в себя имя метода; объект, владеющий методом; значения параметров метода.
  • Допустим, у нас есть объекты Invoker (Командир) и Receiver (Исполнитель). Этот паттерн использует реализацию интерфейса «Команда», чтобы вызвать некий метод Исполнителя используя для этого известный Командиру метод «execute()». Командир просто знает, что нужно вызвать метод “execute()”, для обработки команды клиента, не разбираясь в деталях реализации Исполнителя. Исполнитель отделен от Командира.
  • Вторым аспектом этого паттерна является метод undo(), который отменяет действие, выполняемое методом execute(). Команды также могут быть объединены в более общие команды с минимальным копированием-вставкой и полагаясь на композицию поверх наследования.
  • Пример: https://github.com/deuterium7/command-test

Итератор (Iterator)

  • Используется для перемещения по контейнеру и обеспечения доступа к элементам контейнера.
  • Аналогия: Радиоприёмник. Вы начинаете с какой-то радиостанции, а затем перемещаетесь по станциям вперёд/назад. То есть устройство предоставляет интерфейс для итерирования по каналам.
  • Зачастую этот паттерн используется вместо массива объектов, чтобы не только предоставить доступ к элементам, но и наделить некоторой логикой. Это может быть ограничение доступа, сортировка или любая другая операция над множеством объектов.
  • Пример: https://github.com/deuterium7/iterator-test

31.10.2017:

Посредник (Mediator)

  • Обеспечивающий взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
  • Шаблон помогает уменьшить связанность (coupling) классов, общающихся друг с другом, ведь теперь они не должны знать о реализациях своих собеседников.
  • «Посредник» определяет интерфейс для обмена информацией с объектами «Коллеги», «Конкретный посредник» координирует действия объектов «Коллеги». Каждый класс «Коллеги» знает о своем объекте «Посредник», все «Коллеги» обмениваются информацией только с посредником, при его отсутствии им пришлось бы обмениваться информацией напрямую. «Коллеги» посылают запросы посреднику и получают запросы от него. «Посредник» реализует кооперативное поведение, пересылая каждый запрос одному или нескольким «Коллегам».
  • Аналогия: Когда вы говорите с кем-то по мобильнику, то между вами и собеседником находится мобильный оператор. То есть сигнал передаётся через него, а не напрямую. В данном примере оператор — посредник.
  • Пример: https://github.com/deuterium7/mediator-test

Хранитель (Memento)

  • Поведенческий шаблон проектирования, позволяющий, не нарушая инкапсуляцию, зафиксировать и сохранить внутреннее состояние объекта так, чтобы позднее восстановить его в это состояние.
  • Классический вариант: Шаблон Хранитель используется двумя объектами: «Создателем» (originator) и «Опекуном» (caretaker). «Создатель» — это объект, у которого есть внутреннее состояние. Объект «Опекун» может производить некоторые действия с «Создателем», но при этом необходимо иметь возможность откатить изменения. Для этого «Опекун» запрашивает у «Создателя» объект «Хранителя». Затем выполняет запланированное действие (или последовательность действий). Для выполнения отката «Создателя» к состоянию, которое предшествовало изменениям, «Опекун» возвращает объект «Хранителя» его «Создателю». «Хранитель» является непрозрачным (то есть таким, который не может или не должен изменяться «Опекуном»).
  • Аналогия: В качестве примера можно привести калькулятор («создатель»), у которого любая последняя выполненная операция сохраняется в памяти («хранитель»), чтобы вы могли снова вызвать её с помощью каких-то кнопок («опекун»).
  • Пример: https://github.com/deuterium7/memento-test

Объект Null (Null Object)

  • Null Object — это объект с определенным нейтральным («null») поведением. Шаблон проектирования Null Object описывает использование таких объектов и их поведение (или отсутствие такового).
  • Методы, которые возвращают объект или Null, вместо этого должны вернуть объект NullObject. Это упрощённый формальный код, устраняющий необходимость проверки:
  if (!is_null($obj)) { 
    $obj->callSomething();
  }

заменяя её на обычный вызов:

  $obj->callSomething();

Наблюдатель (Observer)

  • Также известен как «подчинённые» (Dependents). Создает механизм у класса, который позволяет получать экземпляру объекта этого класса оповещения от других объектов об изменении их состояния, тем самым наблюдая за ними.
  • В шаблоне «Наблюдатель» есть объект («субъект»), ведущий список своих «подчинённых» («наблюдателей») и автоматически уведомляющий их о любом изменении своего состояния, обычно с помощью вызова одного из их методов.
  • Паттерн используется, чтобы сократить количество связанных напрямую объектов и вместо этого использует слабую связь (loose coupling).
  • Аналогия: Люди, ищущие работу, подписываются на публикации на сайтах вакансий и получают уведомления, когда появляются вакансии, подходящие по параметрам.
  • Пример: https://github.com/deuterium7/observer-test

Спецификация (Specification)

  • Шаблон проектирования, посредством которого представление правил бизнес логики может быть преобразовано в виде цепочки объектов, связанных операциями булевой логики.
  • Строит ясное описание бизнес-правил, на соответствие которым могут быть проверены объекты. Композитный класс спецификация имеет один метод, называемый isSatisfiedBy, который возвращает истину или ложь в зависимости от того, удовлетворяет ли данный объект спецификации.
  • Пример: https://github.com/deuterium7/specification-test

Состояние (State)

  • Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
  • Аналогия: Допустим, в графическом редакторе вы выбрали инструмент «Кисть». Она меняет своё поведение в зависимости от настройки цвета: т.е. рисует линию выбранного цвета.
  • Шаблон «Состояние» реализует машину состояний объектно ориентированным способом. Это достигается с помощью:
  1. Реализации каждого состояния в виде производного класса интерфейса шаблона «Состояние»,
  2. Реализации переходов состояний (state transitions) посредством вызова методов, определённых вышестоящим классом (superclass).
  • Шаблон «Состояние» — это в некотором плане шаблон «Стратегия», при котором возможно переключение текущей стратегии с помощью вызова методов, определённых в интерфейсе шаблона.
  • Пример: https://github.com/deuterium7/state-test

Стратегия (Strategy)

  • Стратегия (англ. Strategy) — поведенческий шаблон проектирования, предназначенный для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости. Это позволяет выбирать алгоритм путём определения соответствующего класса. Шаблон Strategy позволяет менять выбранный алгоритм независимо от объектов-клиентов, которые его используют.
  • Аналогия: Возьмём пример с пузырьковой сортировкой. Мы её реализовали, но с ростом объёмов данных сортировка стала выполняться очень медленно. Тогда мы сделали быструю сортировку (Quick sort). Алгоритм работает быстрее на больших объёмах, но на маленьких он очень медленный. Тогда мы реализовали стратегию, при которой для маленьких объёмов данных используется пузырьковая сортировка, а для больших — быстрая.
  • Этот паттерн является хорошей альтернативой наследованию (вместо расширения абстрактного класса).
  • Пример: https://github.com/deuterium7/strategy-test

Шаблонный Метод (Template Method)

  • Шаблонный метод (англ. Template method) — поведенческий шаблон проектирования, определяющий основу алгоритма и позволяющий наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом.
  • Аналогия: Допустим, вы собрались строить дома. Этапы будут такими:
  1. Подготовка фундамента.
  2. Возведение стен.
  3. Настил крыши.
  4. Настил перекрытий. Порядок этапов никогда не меняется. Вы не настелите крышу до возведения стен — и т. д. Но каждый этап модифицируется: стены, например, можно возвести из дерева, кирпича или газобетона.
  • Это каркас алгоритма, который хорошо подходит для библиотек (в фреймворках, например). Пользователь просто реализует уточняющие методы, а суперкласс делает всю основную работу.
  • Пример: https://github.com/deuterium7/template-method-test

Посетитель (Visitor)

  • Шаблон «Посетитель» — это способ отделения алгоритма от структуры объекта, в которой он оперирует. Результат отделения — возможность добавлять новые операции в существующие структуры объектов без их модифицирования. Это один из способов соблюдения принципа открытости/закрытости (open/closed principle).
  • Аналогия: Туристы собрались в Дубай. Сначала им нужен способ попасть туда (виза). После прибытия они будут посещать любую часть города, не спрашивая разрешения, ходить где вздумается. Просто скажите им о каком-нибудь месте — и туристы могут там побывать. Шаблон «Посетитель» помогает добавлять места для посещения.
  • Шаблон «Посетитель» выполняет операции над объектами других классов. Главной целью является сохранение разделения направленности задач отдельных классов. При этом классы обязаны определить специальный контракт, чтобы позволить использовать их Посетителям (метод accept).
  • Пример: https://github.com/deuterium7/visitor-test

01.11.2017:

Делегрование (Delegation)

  • Делегирование (англ. Delegation) — основной шаблон проектирования, в котором объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту. Шаблон делегирования является фундаментальной абстракцией, на основе которой реализованы другие шаблоны — композиция (также называемая агрегацией), примеси (mixins) и аспекты (aspects).
  • Цель: Возможность изменить поведение конкретного экземпляра объекта вместо создания нового класса путемнаследования.
  • Минусы: Этот шаблон обычно затрудняет оптимизацию по скорости в пользу улучшенной чистоты абстракции.
  • Пример: https://github.com/deuterium7/delegation-test

Локатор Служб (Service Locator)

  • Локатор служб — это шаблон проектирования, используемый в разработке программного обеспечения для инкапсуляции процессов, связанных с получением какого-либо сервиса с сильным уровнем абстракции. Этот шаблон использует центральный реестр, известный как «локатор сервисов», который по запросу возвращает информацию (как правило это объекты), необходимую для выполнения определенной задачи. Обратите внимание, что в некотором случае, локатор служб фактически является анти-шаблоном.
  • Аналогия: Пускай задача стоит доставить пакет сока, созданный строителем, фабрикой или ещё чем, куда захотел покупатель. Мы говорим локатору «дай нам службу доставки», и просим службу доставить сок по нужному адресу. Сегодня одна служба, а завтра может быть другая. Нам без разницы какая это конкретно служба, нам важно знать, что эта служба доставит то, что мы ей скажем и туда, куда скажем. В свою очередь службы реализуют интерфейс «Доставить <предмет> на <адрес>».
  • Пример: https://github.com/deuterium7/service-locator-test

Хранилище (Repository)

  • Посредник между уровнями области определения (хранилище) и распределения данных. Использует интерфейс, похожий на коллекции, для доступа к объектам области определения. Репозиторий инкапсулирует набор объектов, сохраняемых в хранилище данных, и операции выполняемые над ними, обеспечивая более объектно-ориентированное представление реальных данных. Репозиторий также преследует цель достижения полного разделения и односторонней зависимости между уровнями области определения и распределения данных.
  • Вероятно, наиболее важным отличием репозиториев является то, что они представляют собой коллекции объектов. Они не описывают хранение в базах данных или кэширование или решение любой другой технической проблемы. Репозитории представляют коллекции.
  • Основное преимущество репозиториев — это абстрактный механизм хранения для коллекций сущностей.
  • Пример: https://github.com/deuterium7/repository-test

Сущность-Атрибут-Значение (Entity Attribute Value)

  • Модель Сущность-Атрибут-Значение (EAV) — это модель данных, предназначенная для описания сущностей, в которых количество атрибутов (свойств, параметров), характеризующих их, потенциально огромно, но то количество, которое реально будет использоваться в конкретной сущности относительно мало.
  • Пример: https://github.com/deuterium7/entity-attribute-value-test