Skip to content

Instantly share code, notes, and snippets.

@DmitriiNazimov
Last active April 25, 2024 15:22
Show Gist options
  • Save DmitriiNazimov/5118966f4955025d6c4967243bbefabe to your computer and use it in GitHub Desktop.
Save DmitriiNazimov/5118966f4955025d6c4967243bbefabe to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ДЕКОРАТОР (decorator)] #Паттерны #ООП #js #ES6
/**
*
* ПАТТЕРН ДЕКОРАТОР (обертка)
* Позволяет наделить обьект новыми возможностями не меняя первоначальный класс и не создавая дочерние классы
* Принцип работы: декоратор помещает целевой обьект в обьект обертку, кот-й запускает базовое поведение обьекта,
* а затем добавляет/отнимает что-то свое.
*
*/
class interface_Coffee {
constructor() {
if (this.constructor.name === 'Creator') {
throw new Error(`${this.constructor.name}: can not create instance of interface`);
}
}
getCost() {
throw new Error(`Не описан метод getCost() в классе ${this.constructor.name}`);
}
getDescription() {
throw new Error(`Не описан метод getDescription() в классе ${this.constructor.name}`);
}
}
class StandartCoffee extends interface_Coffee {
cost = 10;
getCost() {
return this.cost
}
getDescription() {
return 'Standart coffee'
}
}
class MilkCoffee extends interface_Coffee {
constructor(coffee) {
super();
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 2
}
getDescription() {
return this.coffee.getDescription() + ', milk'
}
}
class WhipCoffee extends interface_Coffee {
constructor(coffee) {
super();
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 5
}
getDescription() {
return this.coffee.getDescription() + ', whip'
}
}
class VanillaCoffee extends interface_Coffee {
constructor(coffee) {
super();
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 3
}
getDescription() {
return this.coffee.getDescription() + ', vanilla'
}
}
class DiscountCoffee extends interface_Coffee {
constructor(coffee, percent) {
super();
this.coffee = coffee;
this.percent = percent;
}
// намеренно провоцируем ошибку из интерфейса
// getCost() {
// return this.coffee.getCost() * ((100 - this.percent) / 100);
// }
getDescription() {
return this.coffee.getDescription() + `, with discount ${this.percent}%`
}
}
let someCoffee = new StandartCoffee()
console.log(someCoffee.getCost())// 10
console.log(someCoffee.getDescription())// Простой кофе
someCoffee = new MilkCoffee(someCoffee)
console.log(someCoffee.getCost())// 12
console.log(someCoffee.getDescription())// Простой кофе, молоко
someCoffee = new WhipCoffee(someCoffee)
console.log(someCoffee.getCost())// 17
console.log(someCoffee.getDescription())// Простой кофе, молоко, сливки
someCoffee = new VanillaCoffee(someCoffee)
console.log(someCoffee.getCost())// 20
console.log(someCoffee.getDescription())// Простой кофе, молоко, сливки, ваниль
someCoffee = new DiscountCoffee(someCoffee, 20)
console.log(someCoffee.getCost())// 16
console.log(someCoffee.getDescription())// Простой кофе, молоко, сливки, ваниль, скидка 20%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment