Let's assume we have a simple payment feature on an online shop. We want to manage different transactions with different processors of transactions:
- A transaction can be a payment or a refund.
- A processor of transactions can be Paypal or Payplug.
So we have the following classes:
class PaymentTransaction implements Transaction {
}
class RefundTransaction implements Transaction {
}
class PaypalProcessor implements Processor {
}
class PayplugProcessor implements Processor {
}
What should be a good understanding of OOP?
Processor.process(transaction);
orTransaction.process(processor);
For example, if we take the example 1, how to avoid the following switch
statement?
class PaypalProcessor {
function process(Transaction transaction) {
switch(transaction.getType()) {
case payment:
//..
break;
case refund:
//..
}
}
In all cases, how to manage a "nested" polymorphism, a strategy or something else to be able to manage the different transactions with the different processors?
PS: if the title is not appropriate, tell me I will edit it.
You seem to be on the right track. What you need is a third class for performing the operations (sample code in Java for the sake of discussion) :
You can then inject the appropriate implementation of
Processor
andTransaction
into thePaymentProcessor
:Notice how you're
PaymentProcessor
can be passed different combinations of a Processor and Transaction without the need to have a switch statement.Note that
processor.process(transaction);
sounds more intuitive thantransaction.process(processor)
. Also note that you can consider using the Abstract Factory pattern here since you seem to be creating a family of related objects (different types of processors that process different types of transactions)I would make transaction object responsible for both processing payment and refunds.
Then you'd have concrete ones like this:
Client code that would process transaction payment might look like this:
Notice how the client code is kept in the dark about the concrete way money is transferred (implementation details, paypal or payplug). In other words the client is processing transactions polymorphically because it is coded to an abstract rather than a concrete object.
Customer in this example is the concrete factory for the client code:
if the client was coded in a way it expects to work with an abstract object (e.g. "Shopper") then we'd have an appearance of an Abstract Factory pattern.