Structural Design Pattern
Github link: https://github.com/FrancescoXX/Design-Pattern-Adapter-Javascript
đź“ŚIntroduction
The Adapter pattern is used to allow a new use of an existing interface of a class, with a new interface, using the same methods.
We separate the code well (Single responsibility principle).
We dont need to change the existing class (open/closed principle).
⚡️In short
We have:
Target: Interface the client uses.
Adapter: Transforms the request of the client to a specific request.
Adapteee: Class we want to adapt.
đź’ˇIntent
- Wrap an existing class with a new interface.
- Convert an interface into another one.
- Let classes work together that couldn't otherwise because of incompatible interfaces.
🔧 Apply when (we want to)
- Re-use an existing class, but the interface is not compatible
- Combine unrelated classes with an incompatible interface
âś…Pro
- Single Responsibility Principle: We can separate the different interfaces' logic.
- Open/Closed Principle. We can introduce new adapters without breaking the existing code.
⚠️Cons
- How much adapting does the adapter do? Complex adaptations could be be hard to write
- The overall complexity of the code increases
- We need to introduce new interfaces and classes.
- Sometimes it’s better to change the class. (Not always possible by the way).
🏆 Great for
- Connect to legacy systems
- Adapt one interface to another
/** Adapter Design pattern
*
* Structural Design Pattern
*/
//Target
class LegacyShopper {
constructor() {
this.request = (product, quantity, price) => `${price * quantity}$`;
}
}
// Adapteee
class OnlineShopping {
constructor() {
this.authenticate = (username, password) => console.log(`login logic for...${username} // ${password}`);
this.setProduct = (product) => console.log(`setting product to ${product}`);
this.setQuantity = (quantity) => console.log(`setting quantity to ${quantity}`);
this.applyDiscount = (price) => price * 0.9; // online discount
this.checkout = (quantity, price) => `${(this.applyDiscount(price)) * quantity}$`;
}
}
// Adapter interface
class Adapter {
constructor(username, password) {
const cart = new OnlineShopping();
cart.authenticate(username, password);
this.request = (product, quantity, price) => {
cart.setProduct(product);
cart.setQuantity(quantity);
return cart.checkout(quantity, price);
}
};
}
// legacy shopping
const cart = new LegacyShopper();
console.log("***Legacy system***");
console.log("Standard cost: " + cart.request("apples", 10, 3));
// OUTPUT
//
//***Legacy system***
//Standard cost: 30$
//////////////////////////////////////////////////////////////
// new shopping with Adapted interface
console.log("\n***New system***");
const adapter = new Adapter("Francesco", "123456"); //login logic simulation
//Same request, using the adapter
console.log("Online cost: " + adapter.request("apples", 10, 3)); //27$
// OUTPUT:
//
// ***New system***
// login logic for...Francesco // 123456
// setting product to apples
// setting quantity to 10
// Online cost: 27$
Github link: https://github.com/FrancescoXX/Design-Pattern-Adapter-Javascript