Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AlexManSPB/7a3dcbd7fbcc9e3bb240475fcd61c33c to your computer and use it in GitHub Desktop.
Save AlexManSPB/7a3dcbd7fbcc9e3bb240475fcd61c33c to your computer and use it in GitHub Desktop.

Revisions

  1. @DmitriiNazimov DmitriiNazimov renamed this gist Aug 30, 2019. 1 changed file with 1 addition and 1 deletion.
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    /**
    *
    * ПАТТЕРН ЦЕПОЧКА ОБЯЗАННОСТЕЙ (Chain of Command)
    * ПАТТЕРН ЦЕПОЧКА ОБЯЗАННОСТЕЙ (Chain of responsibility)
    *
    * Паттерн ЦЕПОЧКА ОБЯЗАННОСТЕЙ - это поведенческий паттерн проектирования, который позволяет передавать запросы
    * последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам
  2. @DmitriiNazimov DmitriiNazimov created this gist Aug 27, 2019.
    105 changes: 105 additions & 0 deletions pattern-chain-of-command.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    /**
    *
    * ПАТТЕРН ЦЕПОЧКА ОБЯЗАННОСТЕЙ (Chain of Command)
    *
    * Паттерн ЦЕПОЧКА ОБЯЗАННОСТЕЙ - это поведенческий паттерн проектирования, который позволяет передавать запросы
    * последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам
    * и стоит ли передавать запрос дальше по цепи.
    *
    * Пример: у вас есть три счета (A, B, C) с разными суммами и разным приоритетом использования. Сначала проверяется A,
    * если на нем достаточно денег для покупки, то цепочка прерывается. Иначе проверяется B, затем C. Цепь будет
    * продолжаться, пока не найдет подходящий обработчик.
    *
    */


    class Account {

    setNext(account) {
    this.successor = account
    }

    pay(amountToPay) {
    if (this.canPay(amountToPay)) {
    console.log(`Paid ${amountToPay} using ${this.name}`)
    } else if (this.successor) {
    console.log(`Cannot pay using ${this.name}. Proceeding...`)
    this.successor.pay(amountToPay)
    } else {
    console.log('None of the accounts have enough balance')
    }
    }

    canPay(amount) {
    return this.balance >= amount
    }
    }

    class Bank extends Account {
    constructor(balance) {
    super()
    this.name = 'bank'
    this.balance = balance
    }
    }

    class Paypal extends Account {
    constructor(balance) {
    super()
    this.name = 'Paypal'
    this.balance = balance
    }
    }

    class Bitcoin extends Account {
    constructor(balance) {
    super()
    this.name = 'bitcoin'
    this.balance = balance
    }
    }


    // Сделаем такую цепочку
    // bank->paypal->bitcoin
    //
    // Приоритет у банка!
    // Если банк не может оплатить, переходим к Paypal
    // Если Paypal не может, переходим к Bitcoin

    const bank = new Bank(100) // Bank with balance 100
    const paypal = new Paypal(200) // Paypal with balance 200
    const bitcoin = new Bitcoin(300) // Bitcoin with balance 300

    bank.setNext(paypal)
    paypal.setNext(bitcoin)

    // Начнём с банка
    bank.pay(259)

    // Cannot pay using bank. Proceeding ..
    // Cannot pay using paypal. Proceeding ..:
    // Paid 259 using Bitcoin!




    // Еще один вариант цепочки обязанностей, кумулятивный:
    class CumulativeSum {
    constructor(intialValue = 0) {
    this.sum = intialValue;
    }

    add(value) {
    this.sum += value;
    return this;
    }
    }

    // usage
    const sum1 = new CumulativeSum();
    console.log(sum1.add(10).add(2).add(50)); // 62


    const sum2 = new CumulativeSum(10);
    console.log(sum2.add(10).add(20).add(5)); // 45