Adapter Pattern

Any operating company has its methods to generate receipts. Usually there are one or few vendors which help companies automate their processes. Let's see code. We have special class which takes care of generating receipts. 

class VismaEnterprise {
  
  constructor(amount) {
    this.amount = amount
  }
 
  // main method which generates receipt
  generateReceipt() {
    return this.amount + this.addVatTax()
  }
  
  addVatTax() {
    return this.amount * 0.25
  }
  
}

// in our main dashbord we can use this class

class Dashboard {
  
  constructor(vendor) {
    this.vendor = vendor
  }
  
  generateReceipt() {
    return this.vendor.generateReceipt()
  }
  
}

const receipt = new VismaEnterprise(100); 
const dashboard = new Dashboard(receipt)
dashboard.generateReceipt(); 

// => console.log give use the result of 125 SEK

Now as in any aspect of business life, things change and new vendors enter market and offer better pricing, solutions and etc. Let's imagine that new vendor has enter market and it has its own way to generate receipt. 

class WintEnterprise {
  
  constructor(amount) {
    this.amount = amount
  }
  
  // main method which generates receipt
  produceFaktura() {
    return this.amount * 0.25 + this.includeVatTax() + this.includeTransactionFees()
  }
  
  includeVatTax() {
    return this.amount * 0.25
  }
  
  includeTransactionFees() {
    return this.amount * 0.15
  }
  
}

So in order to use WintEnterprise class all have to do in the MainDashboard class is this

class Dashboard {
  
  constructor(vendor) {
    this.vendor = vendor
  }
  
  // change occured here, we swapped for method which generates receipt
  generateReceipt() {
    return this.vendor.produceFaktura()
  }
  
}

const receipt = new WintEnterprise(100); 
const dashboard = new Dashboard(receipt)

dashboard.generateReceipt(); 

// => 254

To be honest that change was not painful, we just swapped for WintEnterprise class method of generating receipt. We had to change at only one place. However imagine our original dashboard class depended on more methods. 

class Dashboard {
  
  constructor(vendor) {
    this.vendor = vendor
  }
  
  generateReceipt() {
    return this.vendor.generateReceipt()
  }
  
  getCustomerInfo() {
    return this.vendor.getCustomerUUID()
  }
  
  bankAccountDetails() {
    return this.vendor.bankingAccounts()
  }
  
}

As you can see, now we have more methods from VismaEnterprise class, in order to switch to WintEnterprise we have to change at least in three places. In more complex class structure it can get quite messy. Here where we can implement Adapter pattern. In order to do that let us create create a class which will act as adapter. 

class WintEnterpriseAdapter {
  
  constructor(amount) {
    this.wintEnterprise = new WintEnterprise({ amount: this.amount })
  }
  
   generateReceipt() {
    return this.wintEnterprise.produceFaktura()
  }
  
}

// our original class 

class Dashboard {
  
  constructor(vendor) {
    this.vendor = vendor
  }
  
  generateReceipt() {
    return this.vendor.generateReceipt(100)
  }
  
}

const receipt = new WintEnterpriseAdapter(100); 
const dashboard = new Dashboard(receipt)
dashboard.generateReceipt(); 

// => 65

We are done here. I hope it will benefit you in our coding.