Описание
Что будет на курсе:
- Вы научитесь применять проверенные архитектурные подходы при создании программ.
- Вы узнаете, как применять паттерны в разработке алгоритмов разного направления, начиная от интерфейса веб-приложения и заканчивая серверной частью мобильного приложения.
Программа курса
Раздел 1
Введение в паттерны проектирования
Познакомимся с паттернами проектирования, разберёмся, зачем они нужны и на какие типы делятся.
– Что такое паттерны проектирования и зачем их нужно знать?
– Что будет на курсе?
– Процедурное, объектно-ориентированное и функциональное программирование
– Типы паттернов проектирования
– Тест по первому разделу
Раздел 2
Порождающие паттерны
В этом разделе рассмотрим порождающие паттерны проектирования
– Введение: что такое порождающие паттерны, для чего и когда они нужны.
«Одиночка» (Singleton)
– Демо: счётчик посещений в проекте «Котокафе»
– Задание + решение: создание счётчика посещений страниц проекта «Фермерские продукты»
«Фабричный метод» (Factory method) — Фабричный метод (Factory method)
– Демо: выделение карточки в галерее «Котокафе»
– Задание + решение: вывод типов продуктов на главной странице проекта «Фермерские продукты»
«Абстрактная фабрика» (Abstract Factory)
– Демо: изменение формата вывода имени редких котов в проекте «Котокафе»
– Задание + решение: создание шаблонов для карточек и заголовков в проекте «Фермерские продукты»
«Строитель» (Builder)
– Демо: вывод промотекста на страницах проекта «Котокафе»
– Задание + решение: добавление промотекста на страницах проекта «Фермерские продукты»
«Пул объектов» (Object Pool)
– Демо: вывод времени посещения страницы в проекте «Котокафе»
– Задание + решение: вывод времени запуска приложения на главной странице проекта «Фермерские продукты»
«Прототип» (Prototype)
– Демо: создание прототипа с информацией о питомце в проекте «Котокафе»
– Задание + решение: создание прототипа для карточек в проекте «Фермерские продукты»
– Тест по второму разделу
Раздел 3
Структурные паттерны
В этом разделе рассмотрим структурные паттерны проектирования
– Введение в структурные паттерны
«Адаптер» (Adapter)
– Демо: вывод данных в новом формате в сервисе по продаже автомобилей
– Задание + решение: вывод данных в новом формате в CRM-системе
«Мост» (Bridge)
– Демо: изменение цветовой темы сервиса по продаже автомобилей
– Задание + решение: механизм цветового оформления CRM-системы
«Декоратор» (Decorator)
– Демо: ускорение загрузки страниц в сервисе по продаже автомобилей
– Задание + решение: кэширование данных в CRM-системе
«Фасад» (Facade)
– Демо: инкапсуляция базовой конфигурации для новых запросов в сервисе по продаже автомобилей
– Задание + решение: получение задач из внешней CRM-систем
«Компоновщик» (Composite)
– Демо: выделение авто в списке с помощью чекбокса в сервисе по продаже автомобилей
– Задание + решение: выделение задач из списка в CRM-системе
«Прокси» (Proxy)
– Демо: ограничение времени доступа сотрудников к сервису по продаже автомобилей
– Задание + решение: блокировка получения данных в CRM-системе
– Тест по третьему разделу
Раздел 4
Поведенческие паттерны
В этом разделе рассмотрим поведенческие паттерны проектирования
«Цепочка обязанностей» (Chain of Responsibility)
– Демо: вывод в карточку товара информации о наличии книг в проекте «По полочкам»
– Задание + решение: вывод в карточку рецепта данных о количестве блюд в проекте «Ещё кусочек»
«Команда» (Command)
– Демо: получение данных с сервера с помощью AJAX-запроса в проекте «По полочкам»
– Задание + решение: инструмент для получения данных из нового источника в проекте «Ещё кусочек»
«Итератор» (Iterator)
– Демо: блокировка вывода данных в определённый промежуток времени в проекте «По полочкам»
– Задание + решение: блокировка вывода рецептов в определённое время в проекте «Ещё кусочек»
«Посредник» (Mediator)
– Демо: рамка для контейнера с книгами в проекте «По полочкам»
– Задание + решение: рамка для контейнера с рецептами в проекте «Ещё кусочек»
«Наблюдатель» (Observer)
– Демо: внешний скрипт для удаления блока с новинками в проекте «По полочкам»
– Задание + решение: внешний скрипт для удаления некорректных рецептов в проекте «Ещё кусочек»
«Состояние» (State)
– Демо: добавление тёмной темы в проекте «По полочкам»
– Задание + решение: тёмная тема в проекте «Ещё кусочек»
«Стратегия» (Strategy)
– Демо: вывод шаблона карточки товара без блока с количеством страниц в проекте «По полочкам»
– Задание + решение: вывод шаблона карточки рецепта без блока автора в проекте «Ещё кусочек»
«Посетитель» (Visitor)
– Демо: выделение нового издания книги по уникальному идентификатору
– Задание + решение: блокировка рецепта в стадии разработки в проекте «Ещё кусочек»
‘, »],
pagination: false
});
$(‘select[name=’recurring_id’], input[name=»quantity»]’).change(function(){
$.ajax({
url: ‘index.php?route=product/product/getRecurringDescription’,
type: ‘post’,
data: $(‘input[name=’product_id’], input[name=’quantity’], select[name=’recurring_id’]’),
dataType: ‘json’,
beforeSend: function() {
$(‘#recurring-description’).html(»);
},
success: function(json) {
$(‘.alert, .text-danger’).remove();
if (json[‘success’]) {
$(‘#recurring-description’).html(json[‘success’]);
}
}
});
});
$(‘.date’).datetimepicker({
pickTime: false
});
$(‘.datetime’).datetimepicker({
pickDate: true,
pickTime: true
});
$(‘.time’).datetimepicker({
pickDate: false
});
$(‘button[id^=’button-upload’]’).on(‘click’, function() {
var node = this;
$(‘#form-upload’).remove();
$(‘body’).prepend(‘
‘);
$(‘#form-upload input[name=’file’]’).trigger(‘click’);
if (typeof timer != ‘undefined’) {
clearInterval(timer);
}
timer = setInterval(function() {
if ($(‘#form-upload input[name=’file’]’).val() != ») {
clearInterval(timer);
$.ajax({
url: ‘index.php?route=tool/upload’,
type: ‘post’,
dataType: ‘json’,
data: new FormData($(‘#form-upload’)[0]),
cache: false,
contentType: false,
processData: false,
beforeSend: function() {
$(node).button(‘loading’);
},
complete: function() {
$(node).button(‘reset’);
},
success: function(json) {
$(‘.text-danger’).remove();
if (json[‘error’]) {
$(node).parent().find(‘input’).after(‘
‘);
}
if (json[‘success’]) {
alert(json[‘success’]);
$(node).parent().find(‘input’).attr(‘value’, json[‘code’]);
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + «rn» + xhr.statusText + «rn» + xhr.responseText);
}
});
}
}, 500);
});
$(‘#review’).delegate(‘.pagination a’, ‘click’, function(e) {
e.preventDefault();
$(‘#review’).fadeOut(‘slow’);
$(‘#review’).load(this.href);
$(‘#review’).fadeIn(‘slow’);
});
$(‘#review’).load(‘index.php?route=product/product/review&product_id=16810’);
$(‘#button-review’).on(‘click’, function() {
$.ajax({
url: ‘index.php?route=product/product/write&product_id=16810’,
type: ‘post’,
dataType: ‘json’,
data: $(«.form-review»).serialize(),
beforeSend: function() {
$(‘#button-review’).button(‘loading’);
},
complete: function() {
$(‘#button-review’).button(‘reset’);
},
success: function(json) {
$(‘.alert-success, .alert-danger’).remove();
if (json[‘error’]) {
get_revpopup_notification(‘alert-danger’, ‘Ошибка’, json[‘error’]);
}
if (json[‘success’]) {
get_revpopup_notification(‘alert-success’, ‘Спасибо за отзыв’, json[‘success’]);
$(‘input[name=’name’]’).val(»);
$(‘textarea[name=’text’]’).val(»);
$(‘input[name=’rating’]:checked’).prop(‘checked’, false);
$(‘#post-review-box’).slideUp(300);
$(‘#new-review’).focus();
$(‘#open-review-box’).fadeIn(100);
$(‘#close-review-box’).hide();
$(‘#ratings-hidden’).val(»);
$(‘.stars .glyphicon’).removeClass(‘glyphicon-star’).addClass(‘glyphicon-star-empty’);
}
}
});
});
$(‘#button-answers’).on(‘click’, function() {
$.ajax({
url: ‘index.php?route=revolution/revstorereview/writeanswer&product_id=16810’,
type: ‘post’,
dataType: ‘json’,
data: $(«.form-answers»).serialize(),
beforeSend: function() {
$(‘#button-answers’).button(‘loading’);
},
complete: function() {
$(‘#button-answers’).button(‘reset’);
},
success: function(json) {
$(‘.alert-success, .alert-danger’).remove();
if (json[‘error’]) {
get_revpopup_notification(‘alert-danger’, ‘Ошибка’, json[‘error’]);
}
if (json[‘success’]) {
get_revpopup_notification(‘alert-success’, ‘Спасибо за вопрос’, json[‘success’]);
$(‘input[name=’name_answer’]’).val(»);
$(‘textarea[name=’text_answer’]’).val(»);
$(‘#post-answers-box’).slideUp(300);
$(‘#new-answers’).focus();
$(‘#open-answers-box’).fadeIn(100);
$(‘#close-answers-box’).hide();
}
}
});
});
$(‘.thumbnails .main-image’).magnificPopup({
type:’image’,
removalDelay: 170,
callbacks: {
beforeOpen: function() {
this.st.mainClass = ‘mfp-zoom-in’;
},
open: function() {
$(‘body’).addClass(‘razmiv2’);
$(‘#pagefader2’).fadeIn(70);
if (document.body.scrollHeight > document.body.offsetHeight) {
}
},
close: function() {
$(‘body’).removeClass(‘razmiv2’);
$(‘#pagefader2’).fadeOut(70);
$(‘#top3’).css(‘right’, ‘initial’);
}
}
});
$(‘.thumbnails .images-additional’).magnificPopup({
type:’image’,
delegate: ‘a’,
gallery: {
enabled:true
},
removalDelay: 170,
callbacks: {
beforeOpen: function() {
this.st.mainClass = ‘mfp-zoom-in’;
},
open: function() {
$(‘body’).addClass(‘razmiv2’);
$(‘#pagefader2’).fadeIn(70);
if (document.body.scrollHeight > document.body.offsetHeight) {
}
},
close: function() {
$(‘body’).removeClass(‘razmiv2’);
$(‘#pagefader2’).fadeOut(70);
$(‘#top3’).css(‘right’, ‘initial’);
}
}
});
$(‘.thumbnails .main-image img’).click(function(){
if ($(‘.images-additional’).length > 0) {
var startnumber = $(this).parent().attr(‘data-number’);
$(‘.images-additional’).magnificPopup(‘open’, startnumber);
return false
} else {
$(‘.main-image’).magnificPopup(‘open’);
return false
}
});
function get_revpopup_cart_quantity() {
input_val = $(‘.product-info.product_informationss .plus-minus’).val();
quantity = parseInt(input_val);
return quantity;
}
function validate_pole(val, product_id, znak, minimumvalue, maximumvalue) {
val.value = val.value.replace(/[^d,]/g, »);
if (val.value == ») val.value = minimumvalue;
maximumvalue = Number($(‘.product_informationss .pr_quantity’).text());
if (maximumvalue 1) maximumvalue = 9999;
input_val = $(‘.product-info.product_informationss .plus-minus’);
quantity = parseInt(input_val.val());
if(znak==’+’) input_val.val(quantity+1);
else if(znak==’-‘ && input_val.val() > minimumvalue) input_val.val(quantity-1);
else if(znak==’=’ && input_val.val() > minimumvalue) input_val.val(input_val.val());
if (quantity 1 || quantity minimumvalue) {
input_val.val(minimumvalue);
val.value = minimumvalue;
}
update_quantity(product_id, input_val.val());
}
function update_quantity(product_id, quantity) {
var minimumvalue = 1;
if (quantity == 0 || quantity minimumvalue) {
quantity = $(‘.product-info.product_informationss .plus-minus’).val(minimumvalue);
return;
} else if (quantity 1) {
quantity = 1;
return;
}
data = $(‘.product-info.product_informationss input[type=’text’], .product-info.product_informationss input[type=’hidden’], .product-info.product_informationss input[type=’radio’]:checked, .product-info.product_informationss input[type=’checkbox’]:checked, .product-info.product_informationss select, .product-info.product_informationss textarea’),
$.ajax({
url: ‘index.php?route=product/product/update_prices’,
type: ‘post’,
dataType: ‘json’,
data: data.serialize() + ‘&product_id=’ + product_id + ‘&quantity=’ + quantity,
success: function(json) {
var end_quantity = json[‘points’];
var start_quantity = parseFloat($(‘.product_informationss .pr_points’).html().replace(/s*/g,»));
$({val:start_quantity}).animate({val:end_quantity}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .pr_points’).html(number_format(val, product_id));
}
});
var price = json[‘price_n’];
var start_price = parseFloat($(‘.product_informationss .update_price’).html().replace(/s*/g,»));
$({val:start_price}).animate({val:price}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .update_price’).html(price_format(val));
}
});
var special = json[‘special_n’];
var start_special = parseFloat($(‘.product_informationss .update_special’).html().replace(/s*/g,»));
$({val:start_special}).animate({val:special}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .update_special’).html(price_format(val));
}
});
}
});
}
function update_prices_product(product_id, minimumvalue) {
input_val = $(‘.product-info.product_informationss .plus-minus’).val();
if (input_val > minimumvalue) {
input_val = minimumvalue;
$(‘.product-info.product_informationss .plus-minus’).val(minimumvalue);
}
quantity = parseInt(input_val);
data = $(‘.product-info.product_informationss input[type=’text’], .product-info.product_informationss input[type=’hidden’], .product-info.product_informationss input[type=’radio’]:checked, .product-info.product_informationss input[type=’checkbox’]:checked, .product-info.product_informationss select, .product-info.product_informationss textarea’);
$.ajax({
type: ‘post’,
url: ‘index.php?route=product/product/update_prices’,
data: data.serialize() + ‘&product_id=’ + product_id + ‘&quantity=’ + quantity,
dataType: ‘json’,
success: function(json) {
$(‘.product_informationss .thumbnails a.main-image’).attr(‘href’, json[‘opt_image_2_big’]);
$(‘.product_informationss .thumbnails a.main-image img’).attr(‘src’, json[‘opt_image_2’]);
$(‘.product_informationss .thumbnails .images-additional .owl-item:first-child a’).attr(‘href’, json[‘opt_image_2_big’]);
$(‘.product_informationss .thumbnails .images-additional .owl-item:first-child a img’).attr(‘src’, json[‘opt_image_2’]).css(‘width’, 100).css(‘height’, 100);
var end_quantity = json[‘option_quantity’];
var start_quantity = parseFloat($(‘.product_informationss .pr_quantity’).html().replace(/s*/g,»));
$({val:start_quantity}).animate({val:end_quantity}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .pr_quantity’).html(number_format(val, product_id));
}
});
var end_quantity = json[‘points’];
var start_quantity = parseFloat($(‘.product_informationss .pr_points’).html().replace(/s*/g,»));
$({val:start_quantity}).animate({val:end_quantity}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .pr_points’).html(number_format(val, product_id));
}
});
var price = json[‘price_n’];
var start_price = parseFloat($(‘.product_informationss .update_price’).html().replace(/s*/g,»));
$({val:start_price}).animate({val:price}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .update_price’).html(price_format(val));
}
});
var special = json[‘special_n’];
var start_special = parseFloat($(‘.product_informationss .update_special’).html().replace(/s*/g,»));
$({val:start_special}).animate({val:special}, {
duration: 500,
easing: ‘swing’,
step: function(val) {
$(‘.product_informationss .update_special’).html(price_format(val));
}
});
}
});
}
function price_format(n) {
c = 0;
d = ‘.’;
t = ‘ ‘;
s_left = »;
s_right = ‘ руб.’;
n = n * 1.00000000;
i = parseInt(n = Math.abs(n).toFixed(c)) + »;
j = ((j = i.length) > 3) ? j % 3 : 0;
return s_left + (j ? i.substr(0, j) + t : ») + i.substr(j).replace(/(d{3})(?=d)/g, «$1″ + t) + (c ? d + Math.abs(n — i).toFixed(c).slice(2) : ») + s_right;
}
function weight_format(n, product_id) {
c = 2;
d = ‘.’;
t = ‘,’;
i = parseInt(n = Math.abs(n).toFixed(c)) + »;
j = ((j = i.length) > 3) ? j % 3 : 0;
return (j ? i.substr(0, j) + t : ») + i.substr(j).replace(/(d{3})(?=d)/g, «$1″ + t) + (c ? d + Math.abs(n — i).toFixed(c).slice(2) : »);
}
function number_format(n, product_id) {
i = parseInt(n = Math.abs(n).toFixed(0)) + »;
return i;
}
$(‘.product_related .owlproduct’).owlCarousel({
items: 1,
singleItem: true,
mouseDrag: false,
touchDrag: false,
autoPlay: false,
navigation: true,
navigationText: [», »],
pagination: false
});
$(‘.viewed_products .owlproduct’).owlCarousel({
items: 1,
singleItem: true,
mouseDrag: false,
touchDrag: false,
autoPlay: false,
navigation: true,
navigationText: [», »],
pagination: false
});
—>
