SlideShare a Scribd company logo
Выжить с ООП
Макс Гопей
Почему?
Объектно-
Oриентированное
Программирование
7
Почему ООП?
•   Это удобно
•   Это расширяемо
•   Адекватная модель мира
•   Позволяет строить асбтракции
•   Мне так сказали
8
Объект олицетворяет объект
в реальном мире.
9
Объект олицетворяет объект
в реальном мире вашем домене.
10
Класс — это описание объекта
11
Класс — это не область имен
12
Пожалуйста, не делайте так:
use SpatieRegexRegex;
 
// Using `match`
Regex::match('/a/', 'abc'); // `MatchResult` object
Regex::match('/a/', 'abc')->hasMatch(); // true
Regex::match('/a/', 'abc')->result(); // 'a'
01.
02.
03.
04.
05.
06.
13
Вместо:
Regex::match('/a/', 'abc'); // `MatchResult` object
Regex::match('/a/', 'abc')->hasMatch(); // true
Regex::match('/a/', 'abc')->result(); // 'a'
лучше:
$pattern = new Regex('/a/');
$matchingResult = $pattern->match('abc'); // `MatchResult` object
$matchingResult->hasMatch(); // true
$matchingResult->result(); // 'a'
01.
02.
03.
01.
02.
03.
04.
14
Вместо:
Assertion::nullOrMax(null, 42); // success
Assertion::nullOrMax(1, 42); // success
Assertion::nullOrMax(1337, 42); // exception
лучше:
// since PHP 5.6
AssertionnullOrMax(null, 42); // success
AssertionnullOrMax(1, 42); // success
AssertionnullOrMax(1337, 42); // exception
01.
02.
03.
01.
02.
03.
04.
15
Инкапсуляция
16
Реализация меняется
•   разные алгоритмы
•   разные хранилища
•   разные протоколы
17
Абстракция не меняется
18
Наследование
20
Стакан
22
Чашка
23
Динозаврик с ручкой
24
Проектируйте для наследования.
Наследуйте, если спроектировали для этого.
26
Полиморфизм
27
Полиморфизм
Один интерфейс — множество реализаций.
И не важно, какая используется сейчас.
28
interface Container {
public function drop();
}
class Glass implements Container {
public function drop() { /* well, crash */ }
}
class Cup implements Container {
public function drop() { /* well, crash, and throw the handle out */ }
}
class Cat {
public function dropContainer(Container $container) {
$container->drop();
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
29
$cat = new Cat();
$cat->dropContainer(new Glass());
$cat->dropContainer(new Cup());
$cat->runAway();
01.
02.
03.
04.
30
class ContainerCollection implements Iterator {
public function current() : Container { /* ... */ };
// ...
}
 
$containersOnTable = new ContainerCollection();
 
// Your mom fills the collection here:
$eventManager->dispatch('serve_table', $containers);
 
array_walk($containersOnTable,
function(Container $container) use ($cat) {
$cat->dropContainer($container);
}
);
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
31
Инкапсуляция помогает скрыть реализацию за абстракицей.
Наследование помогает строить абстракции.
Полиморфизм помогает писать код на основе абстракций.
32
33
Методы классов
34
class SearchEngine {
public function indexProduct(Product $product) {
$this->productIndex->add($product);
$indexIsUpToDate = $this->productIndex->isUpToDate();
//..
}
}
01.
02.
03.
04.
05.
06.
07.
35
Три вида сообщений:
•   Команда
•   Запрос
•   Документ
36
Метод-команда
•   принимает запрос на изменение состояния объекта,
•   ничего не возвращает (void),
•   выполняется успешно, либо бросает исключение.
37
Метод-запрос
•   принимает запрос на получение информации,
•   возвращает значение указанного типа,
•   если это невозможно, возвращает NULL ,
•   или бросает исключение,
•   никогда не меняет наблюдаемое состояние объекта.
*
*
38
Документ
•   результат работы метода-запроса.
39
Принцип:
Command Query Separation (CQS)
40
Избегайте сеттеров
41
class Person {
private $firstName, $lastName, $gender, $email;
// __constructor()
// getters
// setters
}
 
$person = new Person('Sheldon', 'Cooper', 'M', 'shelly@gmail.com');
render($person);
01.
02.
03.
04.
05.
06.
07.
08.
09.
42
class Person {
private $firstName, $lastName, $gender, $email;
// __constructor()
// getters
// setters
}
 
$person = new Person('Sheldon', 'Cooper', 'M', 'shelly@gmail.com');
 
$person->setFirstName('Penny');
$person->setGender('F');
 
render($person);
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
44
Отдавайте предпочтение
неизменяемым объектам
(immutables)
46
class Person {
private $firstName, $lastName, $email, $gender;
 
public function rename(NameChangingRequest $request) {
// change first/last/... names depending on request
// throw exception if name is not male, for instance
}
 
public function changeGender(GenderChangingRequest $request) {
// A request which contains also the new name,
// maybe the reason or whatever is needed.
}
}
 
$person->changeGender(new GenderChangingRequest('M', 'New Name'));
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
47
Метод — это транзакция
48
class Product {
public function reduceQuantity($deltaQuantity) {
$this->quantity -= $deltaQuantity;
}
public function verifyStockAvailability() {
if ($this->quantity == 0) {
$this->removeFromStock();
}
}
}
 
$product->reduceQuantity($orderedQuantity);
$product->verifyStockAvailability();
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
49
class Product {
private function reduceQuantity($deltaQuantity) { /*...*/ }
private function verifyStockAvailability() { /*...*/ }
 
public function takeFromStock($quantity) {
try {
$this->reduceQuantity($orderedQuantity);
$this->verifyStockAvailability();
} catch() {
// ...
}
}
}
 
$product->takeFromStock($orderedQuantity);
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
50
Название — это интерфейс
51
function getProductUrl($product) {
return '/'
. str_replace(' ', '-', strtolower($product));
}
01.
02.
03.
04.
52
$product = 'Ski Boots'; // product name
$product = 456; // product id
$product = [ // product data
'id' => 456,
'name' => 'Ski Boots'
];
01.
02.
03.
04.
05.
06.
53
Name things by their real value
•   $product — object
•   $productName — string
•   $productId — integer / hash
•   $productData — array / structure
54
Объекты-значения
(value-objects)
55
$person->addContactInformation(
new EmailAddress('max.gopey@gmail.com')
);
$person->addContactInformation(
new LinkedInProfileUrl('@max.gopey')
);
$this->redirect(new Url('https://stackoverflow.com'));
01.
02.
03.
04.
05.
06.
07.
56
Объекты-значения не изменяются.
57
Немного практики
58
Интернет-аптека для ветеринаров.
Можно покупать товар:
•   для клиники (clinic),
•   для клиента (pet owner).
От этого зависит процесс заказа. Например, при заказе для
клиента можно оформить доставку в клинику или на дом.
59
class Cgi_Nda_Model_Order_Mode
{
const ORDER_MODE_CLINIC = 1;
const ORDER_MODE_PET_OWNER = 2;
}
01.
02.
03.
04.
05.
60
class Cgi_Nda_Model_Session
{
public function getOrderMode() : int {
return $this->getSessionValue('order_mode');
}
}
01.
02.
03.
04.
05.
06.
61
class Cgi_Nda_Block_Order_Mode_Info
{
public function getOrderMode () {
$orderMode = $this->_getSession()->getOrderMode();
if ($orderMode ) {
if ($orderMode == Cgi_Nda_Model_Order_Mode::ORDER_MODE_PET_OWNER) {
return 'For pet owner' ;
} elseif ($orderMode == Cgi_Nda_Model_Order_Mode::ORDER_MODE_CLINIC) {
return 'For clinic' ;
} else {
return false;
}
} else {
return false;
}
}
public function isSeparateShippingAddressAllowed ()
{
$orderMode = $this->_getSession()->getOrderMode();
return $orderMode &&
$orderMode == Cgi_Nda_Model_Order_Mode::ORDER_MODE_PET_OWNER
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
62
interface Cgi_Nda_Model_Order_Mode_Interface
{
public function getCode() : int;
public function getTitle() : string;
public function isSeparateShippingAddressAllowed() : bool;
}
01.
02.
03.
04.
05.
06.
07.
08.
63
class Cgi_Nda_Model_Order_Mode_Clinicimplements Cgi_Nda_Model_Order_Mode_Interface
{
public function getCode() : int {
return 1;
}
public function getTitle() : string {
return 'For Clinic';
}
public function isSeparateShippingAddressAllowed() : bool {
return false;
}
}
 
class Cgi_Nda_Model_Order_Mode_PetOwnerimplements Cgi_Nda_Model_Order_Mode_Interface
{
public function getCode() : int {
return 2;
}
public function getTitle() : string {
return 'For Pet Owner';
}
public function isSeparateShippingAddressAllowed() : bool {
return true;
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
64
class Cgi_Nda_Model_Session
{
public function getOrderMode()
: Cgi_Nda_Model_Order_Mode_Interface {
return $this->getSessionValue('order_mode');
}
}
01.
02.
03.
04.
05.
06.
07.
65
class Cgi_Nda_Block_Order_Mode_Info
{
private $orderMode;
public function __construct(
Cgi_Nda_Model_Order_Mode_Interface $orderMode
) {
$this->orderMode = $orderMode;
}
public function getOrderModeTitle() {
return $this->orderMode->getTitle();
}
public function isSeparateShippingAddressAllowed() {
return $this->orderMode->isSeparateShippingAddressAllowed();
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
66
Выжить с помощью ООП. Максим Гопей

More Related Content

What's hot

Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. Databases
Sergey Nemchinsky
 
Javascript
JavascriptJavascript
Javascript
Vasya Petrov
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
GeeksLab Odessa
 
XPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriverXPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriver
Илья Кожухов
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
Яковенко Кирилл
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
Igor Shkulipa
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
Индексирование в Magento
Индексирование в MagentoИндексирование в Magento
Индексирование в MagentoMagecom Ukraine
 
Шаблоны проектирования 1
Шаблоны проектирования 1Шаблоны проектирования 1
Шаблоны проектирования 1
Constantin Kichinsky
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
Alexander Byndyu
 
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
HappyDev
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
Все дороги ведут в Checkout
Все дороги ведут в CheckoutВсе дороги ведут в Checkout
Все дороги ведут в CheckoutMagecom Ukraine
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoMoscowDjango
 
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)Ontico
 
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...Ontico
 
Web весна 2013 лекция 4
Web весна 2013 лекция 4Web весна 2013 лекция 4
Web весна 2013 лекция 4Technopark
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql InjectionDmitry Evteev
 

What's hot (20)

Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. Databases
 
Javascript
JavascriptJavascript
Javascript
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
 
XPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriverXPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriver
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Индексирование в Magento
Индексирование в MagentoИндексирование в Magento
Индексирование в Magento
 
Шаблоны проектирования 1
Шаблоны проектирования 1Шаблоны проектирования 1
Шаблоны проектирования 1
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
 
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Bytecode
BytecodeBytecode
Bytecode
 
Все дороги ведут в Checkout
Все дороги ведут в CheckoutВсе дороги ведут в Checkout
Все дороги ведут в Checkout
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на Django
 
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)
JavaScript в терминах БЭМ / Владимир Варанкин (Яндекс)
 
JRebel
JRebelJRebel
JRebel
 
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить / Сергей Авер...
 
Web весна 2013 лекция 4
Web весна 2013 лекция 4Web весна 2013 лекция 4
Web весна 2013 лекция 4
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql Injection
 

Similar to Выжить с помощью ООП. Максим Гопей

Толстая модель. История разработки ORM
Толстая модель. История разработки ORMТолстая модель. История разработки ORM
Толстая модель. История разработки ORM
Mikhail Shamin
 
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)ZFConf Conference
 
Объектное и прототипное программирование в Javascript
Объектное и прототипное программирование в JavascriptОбъектное и прототипное программирование в Javascript
Объектное и прототипное программирование в Javascript
Denis Latushkin
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Andrey Rebrov
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
Yandex
 
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
Dev2Dev
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
Омские ИТ-субботники
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
MoscowDjango
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый старт
Antonio
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
DevDay
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование верстки
Talks&Works
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
it-people
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriver
Igor Khrol
 
Seamy side of autotests
Seamy side of autotestsSeamy side of autotests
Seamy side of autotests
Anton Stepanenko
 
Yii2
Yii2Yii2
Yii2
Noveo
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScript
Timur Shemsedinov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 

Similar to Выжить с помощью ООП. Максим Гопей (20)

Толстая модель. История разработки ORM
Толстая модель. История разработки ORMТолстая модель. История разработки ORM
Толстая модель. История разработки ORM
 
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
 
Объектное и прототипное программирование в Javascript
Объектное и прототипное программирование в JavascriptОбъектное и прототипное программирование в Javascript
Объектное и прототипное программирование в Javascript
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
 
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
 
бегун
бегунбегун
бегун
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый старт
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование верстки
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriver
 
Seamy side of autotests
Seamy side of autotestsSeamy side of autotests
Seamy side of autotests
 
Yii2
Yii2Yii2
Yii2
 
бегун
бегунбегун
бегун
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScript
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 

More from EatDog

Классифицируем текст в iOS без CoreML: как и зачем?
Классифицируем текст в iOS без CoreML: как и зачем? Классифицируем текст в iOS без CoreML: как и зачем?
Классифицируем текст в iOS без CoreML: как и зачем?
EatDog
 
macOS app development for iOS devs: expand your horizons
macOS app development for iOS devs: expand your horizonsmacOS app development for iOS devs: expand your horizons
macOS app development for iOS devs: expand your horizons
EatDog
 
Dependency Injections in Kotlin
Dependency Injections in KotlinDependency Injections in Kotlin
Dependency Injections in Kotlin
EatDog
 
Быстрый в имплементации и в работе мониторинг с использованием ELK
Быстрый в имплементации и в работе мониторинг с использованием ELKБыстрый в имплементации и в работе мониторинг с использованием ELK
Быстрый в имплементации и в работе мониторинг с использованием ELK
EatDog
 
Continuous integration / continuous delivery
Continuous integration / continuous deliveryContinuous integration / continuous delivery
Continuous integration / continuous delivery
EatDog
 
Как мы экспериментируем в больших микросервисных системах
Как мы экспериментируем в больших микросервисных системахКак мы экспериментируем в больших микросервисных системах
Как мы экспериментируем в больших микросервисных системах
EatDog
 
Отказоустойчивый Redis кластер
Отказоустойчивый Redis кластерОтказоустойчивый Redis кластер
Отказоустойчивый Redis кластер
EatDog
 
Кодстайл и насилие.
Кодстайл и насилие. Кодстайл и насилие.
Кодстайл и насилие.
EatDog
 
Refactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project ReactorRefactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project Reactor
EatDog
 
GraphQL: APIs the New Way.
GraphQL: APIs the New Way.GraphQL: APIs the New Way.
GraphQL: APIs the New Way.
EatDog
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
EatDog
 
Microservices in a Wild.
Microservices in a Wild.Microservices in a Wild.
Microservices in a Wild.
EatDog
 
Dependency Rejection and TDD without Mocks
Dependency Rejection and TDD without MocksDependency Rejection and TDD without Mocks
Dependency Rejection and TDD without Mocks
EatDog
 
Стероиды для Дотнетчика
Стероиды для ДотнетчикаСтероиды для Дотнетчика
Стероиды для Дотнетчика
EatDog
 
Domain Driven Design – просто о сложном.
Domain Driven Design – просто о сложном.Domain Driven Design – просто о сложном.
Domain Driven Design – просто о сложном.
EatDog
 
OWASP: безопасное программирование на PHP.
OWASP: безопасное программирование на PHP.OWASP: безопасное программирование на PHP.
OWASP: безопасное программирование на PHP.
EatDog
 
Принципы Solid на практике
Принципы Solid на практикеПринципы Solid на практике
Принципы Solid на практике
EatDog
 
Mapbox GL: как работают современные векторные карты
Mapbox GL: как работают современные векторные картыMapbox GL: как работают современные векторные карты
Mapbox GL: как работают современные векторные карты
EatDog
 
Нельзя просто так взять и сделать версионирование API
Нельзя просто так взять и сделать версионирование APIНельзя просто так взять и сделать версионирование API
Нельзя просто так взять и сделать версионирование API
EatDog
 
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемостьAPI в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
EatDog
 

More from EatDog (20)

Классифицируем текст в iOS без CoreML: как и зачем?
Классифицируем текст в iOS без CoreML: как и зачем? Классифицируем текст в iOS без CoreML: как и зачем?
Классифицируем текст в iOS без CoreML: как и зачем?
 
macOS app development for iOS devs: expand your horizons
macOS app development for iOS devs: expand your horizonsmacOS app development for iOS devs: expand your horizons
macOS app development for iOS devs: expand your horizons
 
Dependency Injections in Kotlin
Dependency Injections in KotlinDependency Injections in Kotlin
Dependency Injections in Kotlin
 
Быстрый в имплементации и в работе мониторинг с использованием ELK
Быстрый в имплементации и в работе мониторинг с использованием ELKБыстрый в имплементации и в работе мониторинг с использованием ELK
Быстрый в имплементации и в работе мониторинг с использованием ELK
 
Continuous integration / continuous delivery
Continuous integration / continuous deliveryContinuous integration / continuous delivery
Continuous integration / continuous delivery
 
Как мы экспериментируем в больших микросервисных системах
Как мы экспериментируем в больших микросервисных системахКак мы экспериментируем в больших микросервисных системах
Как мы экспериментируем в больших микросервисных системах
 
Отказоустойчивый Redis кластер
Отказоустойчивый Redis кластерОтказоустойчивый Redis кластер
Отказоустойчивый Redis кластер
 
Кодстайл и насилие.
Кодстайл и насилие. Кодстайл и насилие.
Кодстайл и насилие.
 
Refactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project ReactorRefactor to Reactive With Spring 5 and Project Reactor
Refactor to Reactive With Spring 5 and Project Reactor
 
GraphQL: APIs the New Way.
GraphQL: APIs the New Way.GraphQL: APIs the New Way.
GraphQL: APIs the New Way.
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
 
Microservices in a Wild.
Microservices in a Wild.Microservices in a Wild.
Microservices in a Wild.
 
Dependency Rejection and TDD without Mocks
Dependency Rejection and TDD without MocksDependency Rejection and TDD without Mocks
Dependency Rejection and TDD without Mocks
 
Стероиды для Дотнетчика
Стероиды для ДотнетчикаСтероиды для Дотнетчика
Стероиды для Дотнетчика
 
Domain Driven Design – просто о сложном.
Domain Driven Design – просто о сложном.Domain Driven Design – просто о сложном.
Domain Driven Design – просто о сложном.
 
OWASP: безопасное программирование на PHP.
OWASP: безопасное программирование на PHP.OWASP: безопасное программирование на PHP.
OWASP: безопасное программирование на PHP.
 
Принципы Solid на практике
Принципы Solid на практикеПринципы Solid на практике
Принципы Solid на практике
 
Mapbox GL: как работают современные векторные карты
Mapbox GL: как работают современные векторные картыMapbox GL: как работают современные векторные карты
Mapbox GL: как работают современные векторные карты
 
Нельзя просто так взять и сделать версионирование API
Нельзя просто так взять и сделать версионирование APIНельзя просто так взять и сделать версионирование API
Нельзя просто так взять и сделать версионирование API
 
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемостьAPI в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
API в SAAS, с облаком и без: ресурсы, SLA, балансировка, расширяемость
 

Выжить с помощью ООП. Максим Гопей