I have the following code
class Store {
constructor(paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}
purchaseBike(price, quantity) {
if(this.paymentProcessor instanceof StripePaymentProcessor) {
this.paymentProcessor.pay(price * quantity);
} else {
let token = generateToken();
this.paymentProcessor.pay(price * quantity, token, new Date());
}
}
purchaseHelmet(price, quantity) {
if(this.paymentProcessor instanceof StripePaymentProcessor) {
this.paymentProcessor.pay(price * quantity);
} else {
let token = generateToken();
this.paymentProcessor.pay(price * quantity, token, new Date());
}
}
}
function generateToken() {
return 'sdsd1212zwsd';
}
class StripePaymentProcessor {
constructor(user) {
this.stripe = new Stripe(user);
}
pay(amountInDollars) {
this.stripe.makePayment(amountInDollars * 100);
}
}
class PaypalPaymentProcessor {
constructor(user) {
this.paypal = new Paypal();
this.user = user;
}
pay(amountInDollars, token, date) {
this.paypal.makePaypalPayment(this.user,amountInDollars, token, date);
}
}
class Stripe {
constructor(user) {
this.user = user;
}
makePayment(amountInCents) {
console.log(`${this.user} made payment of $${amountInCents / 100} with Stripe`)
}
}
class Paypal {
makePaypalPayment(user, amountInDollars, token, date) {
console.log(`${user} made payment of $${amountInDollars} with Paypal on the following date ${date}`)
}
}
const store = new Store(new StripePaymentProcessor('Andrej'));
store.purchaseBike(200,2);
store.purchaseHelmet(200,2);
// const store = new Store(new PaypalPaymentProcessor('Andrej'));
// // 200 dollars is one bike - and we want 2 bikes
// store.purchaseBike(200, 2);
// store.purchaseHelmet(15,2);
the idea for this code is from this youtube video where i tried to extend the code with more dificcult scenario where the methods from the processors will not have same name and will expect different number of arguments https://www.youtube.com/watch?v=9oHY5TllWaU&t=614s
So we introduce here Processors for some payments, so our code will not be hardcoding the use of paypal or stripe api methods.
So when i can my 'paymethod, in background it knows if it needs to call the
pay` method API from Stripe or from Paypal.
And that works great.My problem is when i need to call my internal pay
method. There for Stripe
it is expecting only one argument,
and for Paypal
it is expecting three arguments.
price * quantity, token, new Date()
.
We are sending just the token simulating authorization things that will happen on the Stripe side.
As you can see i am resolving this with if else statements where i check if it is instance of StripePaymentProcessor
otherwise else statement is called.
Problem with this approach is that in future if we add another paypantpreprocessor with different method arguments, i need to add another if statement. Also there are no just makePayment methods from the payment providers, there are a lot of other methods and i can't hardcode with if else statements every one of them.
How can this be solved ?