Skip to content
Miguel De Rosa edited this page Dec 23, 2023 · 3 revisions

Strategy Design Pattern

Scenary to apply the strategy pattern

Let's go to consider that we work in a company which has an application that creates digitial wallets. A digital wallet in this example is a mobile application which let the users pay goods and services through several payment methods:

  • Debit card
  • Credit card
  • QR
  • Bitcoins

Also, each digital wallet let the users do investments and these e-wallets can be installed on Android and iOS devices.

The digital wallets that supports our application are listed below:

  • Orange Card
  • Sintindir
  • Marquet Pay

And we have the following restrictions:

Payment methods allowed by each e-wallet:

Debit card Credit card QR Bitcoins
Orange Card Yes No No Yes
Sintindir Yes Yes No No
Marquet Pay Yes Yes Yes No

Investement allowed by application:

Mutual investment fund Cryptocurrency buy Foreign currency buy
Orange Card No Yes No
Sintindir Yes No Yes
Marquet Pay Yes No No

Addresing the problem

Our application is constructed by using the programming oriented object paradigm. Where we have a superclass named Ewallet and ever subclass inherits it

imagen

Where:

  • display() is and abstract method that has to be implemented by each wallet according its stetic rules.
  • installOnAndroid() and installOnIos() are concrete methods inherited and used in the same way by each ewallet.
  • pay() and invest() present the issue to address because for these method we have the restriccions mentioned above.

Potential solution 1

Having pay() and invest() methods overrode in each ewallet. But this solution would be hard to maintain because the spec are in constant change.

Potential solution 2

Creating Payable() and Investable() interfaces with pay() and invest() methods respectfully. But with this solutions results in duplicated code.

Potential (and the best one) solution 3: Strategy Pattern

The Strategy pattern defines a family of algorithms, encapsulates it each one, and makes them interchangable.
Strategy lets the algorithm vary independent from clients that use it.

We'll consider the following design principle:

  1. Design principle: Identify the aspects of your application that vary and separate them from what stays the same.

It means that we need to take the parts that vay and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don't. Here we need to extract the pay() and invest() methods because that will be changing in the ewallets. We need to do that extraction by taking into account the following design principle:

  1. Design principle: Program to an interface, not an implementation.

It means that we need to use interfaces (it could be with abstract classes too) in order to represent behaviors. So, we will use the following desing:

imagen

Finally, in order to put all together we'll consider the following design principle:

  1. Favor the composition over inheritance.

We will put a InvestBehavior and a PayBehavior in the Ewallet class. When we put two classes together like this we're using composition. Instead of inheriting their behavior, the ewallets get their behavior by being composed with the right behavior object. So, the final class structure:

imagen