1

I need to add a new payment type to an existing code base. That means that I'm going to have a few methods looking like this:

if (old payment type)
    process old type of payment
else
    process new type of payment

Now, if this could have been determined beforehand, I would have this method point to an interface implementing a common Pay method and then that interface would be implemented by one of two classes. Unfortunately, I only know which method the customer chooses at runtime, which means I need a way to determine which branch to use. Is there another way except for just having ifs spread through the code?

Marcel Popescu
  • 236
  • 1
  • 6
  • 6
    Can't you introduce the Interface right now? – Marcel Jul 29 '13 at 09:09
  • I can, but it wouldn't help. The implementation cannot be determined at compile-time so I would still need an `if` to determine which one to use... wouldn't I? – Marcel Popescu Jul 29 '13 at 09:12
  • 1
    You'd instantiate an object of the required type and there are various ways to do that, some require `IF`, some are just an array lookup. – James Snell Jul 29 '13 at 09:17
  • Hmm... now that I think about it, something like this might work `void DoStuff(IPayment payment)` and call it with `DoStuff(ChoosePayment(...))` where the `if` is only in one place (the `ChoosePayment` method). Would that work? Is there anything I missed? – Marcel Popescu Jul 29 '13 at 09:19
  • I'm not really seeing how this is a duplicate of that question (or the other one linked from it)... those care about a pass/fail condition; in my case, all values are "good", they just determine a different path through the code. – Marcel Popescu Jul 29 '13 at 09:25
  • 3
    @MarcelPopescu You will need to have at least one `if`, however if done right, you will require exactly one `if` which determines which implementation of IPayment to use. If you find yourself with many implementations, consider using a Factory pattern. – Neil Jul 29 '13 at 09:34
  • Ok... the consensus seems to be "add the interface to the method"; if someone wants to write it as an answer I'll accept it. – Marcel Popescu Jul 29 '13 at 10:05

1 Answers1

5

This is textbook example of Strategy pattern.

...a software design pattern, whereby an algorithm's behaviour can be selected at runtime. Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it...

This will allow you to have different implementations of how you pay and you can create the concrete one at runtime based on data saved together with payment.

gnat
  • 21,442
  • 29
  • 112
  • 288
Euphoric
  • 36,735
  • 6
  • 78
  • 110
  • Sorry, that won't work (I considered it). The problem with the Strategy pattern is that the behaviour is selected on object creation (ie, `context = new Context(new Add());`); I don't know which payment method I am going to use when the object is created, I only know that when payment is actually invoked. – Marcel Popescu Jul 29 '13 at 10:42
  • @MarcelPopescu Strategy is normal property. You can change it just like you would normal variable. It is not needed for it to be fixed during it's creation. – Euphoric Jul 29 '13 at 10:44
  • Ah... I missed that part; I was stuck on "it must be set at object creation". Got it. – Marcel Popescu Jul 29 '13 at 11:03