[Разработка веб-сайтов, JavaScript, Программирование, Совершенный код] Как выдать Золушку за принца и не сойти с ума. Паттерн Декоратор
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Всем привет, я Максим Кравец из Holyweb, и мы продолжаем разговор о паттернах (первую статью о Singleton можно почитать вот тут). Героя нашего сегодняшнего сюжета порой называют «wrapper» или «обертка», поскольку он оборачивает исходный код, но мне больше нравится название «декоратор» — оно точнее отражает не механику, а суть происходящего. Приступим.
А кто у нас муж? Волшебник? Предупреждать же надо!Хорошо Золушке — у нее тетя не просто так крестная, а целая добрая фея. Взмах волшебной палочки — и тыква превращается в карету. Еще взмах — и рабочая одежда становится бальным платьем. Две минуты волшебства — и у любого принца шансы отвертеться устремляются к нулю. Мы, конечно, не волшебники. Мы программисты. Но творить чудеса для нашего кода обязаны! Так что создаем класс «Золушка», наделяем ее ангельским характером и пытаемся выдать ее замуж, по возможности — удачно.
class Cinderella {
aboutMe() {
return `ангельский характер`;
};
}
Пришла пора посмотреть на потенциальных супругов:
- Принц Филипп. Обожает скачки, охоту, экстремальный отдых.
- Принц Эдвард. Страстный поклонник танцев и бальных нарядов.
- Принц Артур. Любитель сладостей и выпечки.
Давайте представим нашу Золушку принцу Филлипу:
class Cinderella {
aboutMe() {
return `ангельский характер`;
};
}
const whatPrinceFilippKnows = new Cinderella()
console.log('У Золушки', whatPrinceFilippKnows.aboutMe())
Результат выполнения нашего кода:
У Золушки ангельский характер
Хм… маловато будет. Принц Филипп экстремал, с ним и встретиться-то можно только во время прыжка с тарзанки. На всякий случай добавим:
class Cinderella {
aboutMe() {
return `ангельский характер`;
};
}
class ExtremeCinderella extends Cinderella {
aboutMe() {
return `
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
`
};
}
const whatPrinceFilippKnows = new ExtremeCinderella()
console.log('У Золушки', whatPrinceFilippKnows.aboutMe())
Пожалуй, такой результат нашего принца удовлетворит:
У Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
А вот принцу Эдварду экстрим — до лампочки. Он обожает танцы. Сделаем и ему Золушку его мечты, заодно немного поправим вывод в консоль, чтобы понимать, какому принцу какое счастье достанется:
class Cinderella {
aboutMe() {
return `ангельский характер`
};
}
class ExtremeCinderella extends Cinderella {
aboutMe() {
return `
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
`
};
}
class DanceCinderella extends Cinderella {
aboutMe() {
return `
свой магазин платьев и обуви "Все для бала"
ангельский характер
`
};
}
const whatPrinceFilippKnows = new ExtremeCinderella()
const whatPrinceEdvardKnows = new DanceCinderella()
console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe())
console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe())
Результат выглядит вроде бы неплохо:
Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
Принц Эдвард знает, что у Золушки
свой магазин платьев и обуви «Все для бала»
ангельский характер
Хьюстон, у нас проблема! Даже две Первая — идеологическая. Вернемся ненадолго к опыту тети-феи, которая собирала свою крестницу на бал. Золушка — какой была изначально, такой и оставалась. В нее саму никаких изменений не вносилось! Изменялся только антураж, декорирование. Добавлялась одежда, карета, кучер, туфельки. Но Золушка оставалась Золушкой. Мы же — плодим новые классы с помощью наследования.Вторая проблема — принцев на свете многовато. И запросы у них порой... самые причудливые. Устанешь для каждого создавать отдельный класс. Хочется как в сказке: Золушка отдельно, платье отдельно, тыква, пардон, карета — тем более отдельно. Сложить все в коробку да и выдать ее принцу, пусть сам собирает тот комплект, что его устроит! Золушка и туфельки, Золушка и образование, Золушка и месть гномов… Впрочем, это уже про другое, нас же интересует, как реализовать задуманное. Для начала, давайте вынесем все «дополнительные опции» в отдельные функции. Вторым шагом (волшебники мы или погулять вышли?) прикажем этим функциям обернуть — задекорировать — свойства нашей исходной Золушки, чтобы при обращении к классу Cinderella возвращался не только ее ангельский характер, но и обертка. Согласно Википедии, Декоратор — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.На первый взгляд — вроде бы то, что доктор прописал! Осталось понять, как это реализовать. Наследование не подошло, может быть получится с агрегацией (в более строгой форме — композицией)?
Давайте еще раз внимательно взглянем на базовый класс Золушки и передадим в нашу функцию-обертку ссылку на базовый класс, а также реализуем точно такой же интерфейс. В итоге мы не будем наследовать поведение, мы добавим в обертке ее функционал, а базовую работу попросим выполнить переданную ссылку на класс.
class Cinderella {
aboutMe() {
return `ангельский характер`
};
}
function extremeSet(cinderella) {
this.aboutMe = function () {
return `
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
${cinderella.aboutMe()}
`
}
}
function danceShop(cinderella) {
this.aboutMe = function () {
return `
свой магазин платьев и обуви "Все для бала"
${cinderella.aboutMe()}
`
}
}
function pastryСhef(cinderella) {
this.aboutMe = function () {
return `
диплом кондитера высшей категории
${cinderella.aboutMe()}
`
}
}
const whatPrinceFilippKnows =new extremeSet(new Cinderella())
const whatPrinceEdvardKnows = new danceShop(new Cinderella())
const whatPrinceArturKnows = new pastryСhef(new Cinderella())
const whatPrinceAliKnows = new extremeSet(new danceShop(new pastryСhef(new Cinderella())))
console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe())
console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe())
console.log('Принц Артур знает, что у Золушки', whatPrinceArturKnows.aboutMe())
console.log('Принц Али знает, что у Золушки', whatPrinceAliKnows.aboutMe())
Пока мы пытались разобраться, что к чему, подъехал четвертый принц по имени Али, которому нравится все сразу. Но благодаря паттерну Декораторов мы просто собрали ему нужный набор:
Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
Принц Эдвард знает, что у Золушки
свой магазин платьев и обуви "Все для бала"
ангельский характер
Принц Артур знает, что у Золушки
диплом кондитера высшей категории
ангельский характер
Принц Али знает, что у Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
свой магазин платьев и обуви "Все для бала"
диплом кондитера высшей категории
ангельский характер
Ах эта свадьба, свадьба пела и плясалаИ это — работает! Смело отправляемся в школу волшебства за дипломом. Хотя… мало познакомить, свадьба-то тоже на наших плечах! Так что давайте не мешкая вооружимся все тем же паттерном Декоратор и посчитаем, во что нам это все обойдется.
class Cinderella {
aboutMe() {
return `ангельский характер`
};
}
function extremeSet(cinderella) {
this.aboutMe = function () {
return `
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
${cinderella.aboutMe()}
`
}
}
function danceShop(cinderella) {
this.aboutMe = function () {
return `
свой магазин платьев и обуви "Все для бала"
${cinderella.aboutMe()}
`
}
}
function pastryСhef(cinderella) {
this.aboutMe = function () {
return `
диплом кондитера высшей категории
${cinderella.aboutMe()}
`
}
}
// минимальная стоимость свадьбы, просто посидеть с гостями
class Wedding {
price() {
return 1000
}
}
// добавить свадебный торт
function weddingCake(wedding) {
this.price = function () {
return wedding.price() + 200
}
}
// пригласить оркестр
function jazzBand(wedding) {
this.price = function () {
return wedding.price() + 500
}
}
// приглашенная звезда из соседнего королевства
function superStar(wedding) {
this.price = function () {
return wedding.price() + 100500
}
}
const whatPrinceFilippKnows = new extremeSet(new Cinderella())
const whatPrinceEdvardKnows = new danceShop(new Cinderella())
const whatPrinceArturKnows = new pastryСhef(new Cinderella())
const whatPrinceAliKnows = new extremeSet(new danceShop(new pastryСhef(new Cinderella())))
const weddingPrice = new superStar(new Wedding())
console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe())
console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe())
console.log('Принц Артур знает, что у Золушки', whatPrinceArturKnows.aboutMe())
console.log('Принц Али знает, что у Золушки', whatPrinceAliKnows.aboutMe())
console.log('Бюджет свадьбы', weddingPrice.price())
Остается только собраться с родственниками принца и вдумчиво обсудить необходимость торта, звезды и гостей. Благо для пересчета надо просто собрать новый набор оберток.
Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
ангельский характер
Принц Эдвард знает, что у Золушки
свой магазин платьев и обуви "Все для бала"
ангельский характер
Принц Артур знает, что у Золушки
диплом кондитера высшей категории
ангельский характер
Принц Али знает, что у Золушки
любовь к экстремальному отдыху
5 комплектов альпинистского снаряжения под кроватью
свой магазин платьев и обуви "Все для бала"
диплом кондитера высшей категории
ангельский характер
Бюджет свадьбы 101500
...и жили они долго…Сказочные истории принято завершать фразой про долго и счастливо. Свою задачу — организовать процесс презентации нашей Золушки потенциальному принцу — мы выполнили. Не отвертится. И даже возможные расходы посчитали! Насколько удалось при этом донести смысл и механику работы паттерна Декоратор, решать вам. Если есть интерес, пишите в комментариях — или ответим сразу, или развернем тему еще в одной статье. А если хотите познакомиться с нашей командой ближе, я всегда на связи в Телеграме @maximkravec.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, Go, TypeScript] Обзор Prisma ORM
- [Тестирование IT-систем, Программирование, Проектирование и рефакторинг, Тестирование веб-сервисов] Анатомия юнит-теста
- [Python, Программирование, Карьера в IT-индустрии] Чему нас научил запуск детского курса?
- [Веб-дизайн, Разработка веб-сайтов, CSS, Google Chrome] Контейнерные запросы в CSS (перевод)
- [CMS, Ненормальное программирование, JavaScript, API, Тестирование веб-сервисов] AEM Test Automation — Create Pages via HTTP Requests
- [JavaScript, Node.JS, TypeScript] Yarn 2 — Устанавливаем и разбираемся
- [Программирование, Микросервисы] Способы взаимодействия сервисов друг с другом. Пулинг/пуш. Достоинства/недостатки. Выбор
- [JavaScript, C, Rust, WebAssembly] Оптимизируем производительность: JavaScript (V8) vs AssemblyScript (WebAssembly) (перевод)
- [JavaScript, Разработка мобильных приложений, Разработка под Android, IT-компании] Google удалила IDE DroidScript из магазина Google Play якобы из-за зловреда и обвинила разработчиков в мошенничестве
- [Информационная безопасность, Разработка веб-сайтов, GitHub] GitHub блокирует FLoC от Google на всех страницах, кроме кастомных доменов
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (Программирование), #_sovershennyj_kod (Совершенный код), #_design_patterns, #_jscript, #_javascript, #_singleton, #_decorator, #_wrapper, #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_javascript, #_programmirovanie (
Программирование
), #_sovershennyj_kod (
Совершенный код
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:13
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Всем привет, я Максим Кравец из Holyweb, и мы продолжаем разговор о паттернах (первую статью о Singleton можно почитать вот тут). Героя нашего сегодняшнего сюжета порой называют «wrapper» или «обертка», поскольку он оборачивает исходный код, но мне больше нравится название «декоратор» — оно точнее отражает не механику, а суть происходящего. Приступим. А кто у нас муж? Волшебник? Предупреждать же надо!Хорошо Золушке — у нее тетя не просто так крестная, а целая добрая фея. Взмах волшебной палочки — и тыква превращается в карету. Еще взмах — и рабочая одежда становится бальным платьем. Две минуты волшебства — и у любого принца шансы отвертеться устремляются к нулю. Мы, конечно, не волшебники. Мы программисты. Но творить чудеса для нашего кода обязаны! Так что создаем класс «Золушка», наделяем ее ангельским характером и пытаемся выдать ее замуж, по возможности — удачно. class Cinderella {
aboutMe() { return `ангельский характер`; }; }
class Cinderella {
aboutMe() { return `ангельский характер`; }; } const whatPrinceFilippKnows = new Cinderella() console.log('У Золушки', whatPrinceFilippKnows.aboutMe()) У Золушки ангельский характер
class Cinderella {
aboutMe() { return `ангельский характер`; }; } class ExtremeCinderella extends Cinderella { aboutMe() { return ` любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер ` }; } const whatPrinceFilippKnows = new ExtremeCinderella() console.log('У Золушки', whatPrinceFilippKnows.aboutMe()) У Золушки
любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер class Cinderella {
aboutMe() { return `ангельский характер` }; } class ExtremeCinderella extends Cinderella { aboutMe() { return ` любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер ` }; } class DanceCinderella extends Cinderella { aboutMe() { return ` свой магазин платьев и обуви "Все для бала" ангельский характер ` }; } const whatPrinceFilippKnows = new ExtremeCinderella() const whatPrinceEdvardKnows = new DanceCinderella() console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe()) console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe()) Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер Принц Эдвард знает, что у Золушки свой магазин платьев и обуви «Все для бала» ангельский характер Давайте еще раз внимательно взглянем на базовый класс Золушки и передадим в нашу функцию-обертку ссылку на базовый класс, а также реализуем точно такой же интерфейс. В итоге мы не будем наследовать поведение, мы добавим в обертке ее функционал, а базовую работу попросим выполнить переданную ссылку на класс. class Cinderella {
aboutMe() { return `ангельский характер` }; } function extremeSet(cinderella) { this.aboutMe = function () { return ` любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ${cinderella.aboutMe()} ` } } function danceShop(cinderella) { this.aboutMe = function () { return ` свой магазин платьев и обуви "Все для бала" ${cinderella.aboutMe()} ` } } function pastryСhef(cinderella) { this.aboutMe = function () { return ` диплом кондитера высшей категории ${cinderella.aboutMe()} ` } } const whatPrinceFilippKnows =new extremeSet(new Cinderella()) const whatPrinceEdvardKnows = new danceShop(new Cinderella()) const whatPrinceArturKnows = new pastryСhef(new Cinderella()) const whatPrinceAliKnows = new extremeSet(new danceShop(new pastryСhef(new Cinderella()))) console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe()) console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe()) console.log('Принц Артур знает, что у Золушки', whatPrinceArturKnows.aboutMe()) console.log('Принц Али знает, что у Золушки', whatPrinceAliKnows.aboutMe()) Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер Принц Эдвард знает, что у Золушки свой магазин платьев и обуви "Все для бала" ангельский характер Принц Артур знает, что у Золушки диплом кондитера высшей категории ангельский характер Принц Али знает, что у Золушки любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью свой магазин платьев и обуви "Все для бала" диплом кондитера высшей категории ангельский характер class Cinderella {
aboutMe() { return `ангельский характер` }; } function extremeSet(cinderella) { this.aboutMe = function () { return ` любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ${cinderella.aboutMe()} ` } } function danceShop(cinderella) { this.aboutMe = function () { return ` свой магазин платьев и обуви "Все для бала" ${cinderella.aboutMe()} ` } } function pastryСhef(cinderella) { this.aboutMe = function () { return ` диплом кондитера высшей категории ${cinderella.aboutMe()} ` } } // минимальная стоимость свадьбы, просто посидеть с гостями class Wedding { price() { return 1000 } } // добавить свадебный торт function weddingCake(wedding) { this.price = function () { return wedding.price() + 200 } } // пригласить оркестр function jazzBand(wedding) { this.price = function () { return wedding.price() + 500 } } // приглашенная звезда из соседнего королевства function superStar(wedding) { this.price = function () { return wedding.price() + 100500 } } const whatPrinceFilippKnows = new extremeSet(new Cinderella()) const whatPrinceEdvardKnows = new danceShop(new Cinderella()) const whatPrinceArturKnows = new pastryСhef(new Cinderella()) const whatPrinceAliKnows = new extremeSet(new danceShop(new pastryСhef(new Cinderella()))) const weddingPrice = new superStar(new Wedding()) console.log('Принц Филипп знает, что у Золушки', whatPrinceFilippKnows.aboutMe()) console.log('Принц Эдвард знает, что у Золушки', whatPrinceEdvardKnows.aboutMe()) console.log('Принц Артур знает, что у Золушки', whatPrinceArturKnows.aboutMe()) console.log('Принц Али знает, что у Золушки', whatPrinceAliKnows.aboutMe()) console.log('Бюджет свадьбы', weddingPrice.price()) Принц Филипп знает, что у Золушки
любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью ангельский характер Принц Эдвард знает, что у Золушки свой магазин платьев и обуви "Все для бала" ангельский характер Принц Артур знает, что у Золушки диплом кондитера высшей категории ангельский характер Принц Али знает, что у Золушки любовь к экстремальному отдыху 5 комплектов альпинистского снаряжения под кроватью свой магазин платьев и обуви "Все для бала" диплом кондитера высшей категории ангельский характер Бюджет свадьбы 101500 =========== Источник: habr.com =========== Похожие новости:
Разработка веб-сайтов ), #_javascript, #_programmirovanie ( Программирование ), #_sovershennyj_kod ( Совершенный код ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:13
Часовой пояс: UTC + 5