I am trying to understand the Strategy Pattern in order to utilise it for a problem I have.
The current code looks as such where I have an amount that I want to process based on a payment type.
public class PaymentProcessor {
private PaymentType paymentType;
public void processPayment(double amount) {
if (paymentType == PaymentType.CREDIT_CARD) {
Console.Writeline("Processing credit card payment of amount " + amount);
} else if (paymentType == PaymentType.DEBIT_CARD) {
Console.Writeline("Processing debit card payment of amount " + amount);
} else if (paymentType == PaymentType.PAYPAL) {
Console.Writeline("Processing PayPal payment of amount " + amount);
} else {
throw Exception();
}
}
public void setPaymentType(PaymentType paymentType) {
this.paymentType = paymentType;
}
}
enum PaymentType {
CREDIT_CARD,
DEBIT_CARD,
PAYPAL
}
So based on the strategy pattern I would need to create an interface for all payments
public interface IPaymentStrategy {
void processPayment(double amount);
}
then i need to create concrete implemtations for each class I will only give an example of one but you get the idea.
public class CreditCardPaymentStrategy : IPaymentStrategy {
public void processPayment(double amount) {
Console.Writeline("Processing credit card payment of amount " + amount);
}
}
So all the payment strategies will have a concrete implemntation like above.
Finally using Dependency injection and Dependency Inversion I refactor the payment processor to look like this
public class PaymentProcessor {
private PaymentStrategy paymentStrategy;
public PaymentProcessor(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void processPayment(double amount) {
paymentStrategy.processPayment(amount);
}
}
But heres the bit im missing. Where and how do I implement the conditional logic to select the correct concrete implementation to register against the payment strategy based on a payment type?
I have tried looking online. All the examples I see seem to have another class like a factory that news up the concrete version and passes it into the interface. But Im not sure thats the right way to do it as i dont feel like I should be newing up classes that arent POCOS as my DI container should be doing that. So what am I missing in the strategy to conditionally select the concrete type based on the Payment type? Am i even using the right pattern here as i have seen people compare the strategy pattern to Depedency injection. If thats the cose what pattern is better for the conditional selection rather than registering a concrete class with the interface and having to manually change it in the registration every time I want to use a different payment strategy, but be able to switch between strategies at runtime?
Aucun commentaire:
Enregistrer un commentaire