Responsive Advertisement

JavaScript #12: Strategy design pattern in JavaScript

                                  

Welcome back to series about design pattern in JavaScript. If you didn’t read about this series, here is links for you. Design pattern series.

In this article, we discuss about Strategy design pattern.


Table of contents:

  • What is Strategy design pattern?
  • What is structure of Strategy design pattern?
  • Pratical application

So, let’s go to the contents


What is Strategy design pattern?

Stategy design pattern is a behavioral software design pattern, that enables selecting an algorithm of runtime. Instead of implementing a single algorithm directly, code receives runtime instructions as to which a family of algorithm to use.


What is structure of Stategy design pattern?

Context: selects and executes a variant of the same algorithm at run time.

Strategy interface common to all variants of the algorithm.

One by one extract all algorithms into their own classes. They should all implement the strategy interface.

In context class, add a field for storing a reference to a strategy object. Provide a setter for replacing values of that field. Work with only strategy interface.

Clients must associate it with suitable strategy that matches the way they expect the context to perform its primary job.


Pratical application

In previous article, we build a cart to customers could buy items. Now, after adding to cart, customers pay for the bill and select method of shipping. The problem is we build a system of shipping, which contains free shipping, fast shipping, normal shipping. Let’s see in the casual, how to solve this problem with Strategy design pattern.

First, we will build algorithms that calculate for cases like free shipping, normal shipping and fast shipping.

function FreeShipping() {

    this.calculate = (package) => {

        return package.price + 0

    }

}

 

function NormalShipping() {

    this.calculate = (package) => {

        return package.price + 1.2

    }

}

 

function FastShipping() {

    this.calculate = (package) => {

        return package.price + 1.7

    }

}

 

In theory, we should create a strategy interface and create sub-classes that inherit the properties of the strategy interface. In this problem, we can omit the strategy interface and we can immediately build algorithms. In algorithms, we calculate according to each type will have a different price. And is calculated by taking the value of each package plus shipping.

Next, they will create a context to execute algorithms. In the context we will add a field for storing a reference to a strategy object. Provide a setter for replacing values ​​of that field.

function Shipping() {

    this.type = ''

    this.setType = (type) => {

        this.type = type

    }

    this.calculate = (package) => {

        return this.type.calculate(package)

    }

}

 

Okay! We will create a package together, what algorithm will be used.

const package = {

    goods: ['Book', 'Pen', 'Pencil'],

    weight: 1.5,

    price: 3

}

const shipping = new Shipping()

 

We have created a bag and have the total value of the items. Then, we create the context to execute the algorithms.

Now we will create strategy objects that will be left to the context set and used to calculate the final prices.

const freeShipping = new FreeShipping()

shipping.setType(freeShipping)

console.log("Total price: " + shipping.calculate(package))

// => Total price: 3

const fastShipping = new FastShipping()

shipping.setType(fastShipping)

console.log("Total price: " + shipping.calculate(package))

// => Total price: 4.7

const normalShipping = new NormalShipping()

shipping.setType(normalShipping)

console.log("Total price: " + shipping.calculate(package))

// => Total price: 4.2

 

Awesome! When we want to use an algorithm, we let the context set and use the calculation of that algorithm.

So, we have built a way to calculate the value and shipping on each order. For functional programming, building a program using the Strategy design pattern is quite complicated. Let's change and use functional programming to rebuild this program.

function calculateTotalPrice(package, shippingFee) {

    return package.price + shippingFee

}

 

const package = {

    items: ['Book', 'Pen', 'Pencil'],

    price: 3.5

}

const freeShipping = 0

const fastShipping = 1.7

const normalShipping = 1.2

console.log('Free shipping: ' + calculateTotalPrice(package, freeShipping))

// => Free shipping: 3.5

console.log('Fast shipping: ' + calculateTotalPrice(package, fastShipping))

// => Fast shipping: 5.2

console.log('Normal shipping: ' + calculateTotalPrice(package, normalShipping))

// => Normal shipping: 4.7

 

You can completely build a rig much simpler and don't need to use the Strategy design patter. So, let's look at the pros and cons of the Strategy design pattern.

Pros

Swap algorithms used inside and object at runtime.

Isolate the implementation details of an algorithm form the code that uses it.

Replace inheritance with composition.

Open/Closed Principle, introduce new strategies without having to change the context.

Cons

Few algorithms no need to overcomplicate the programs with new classes and interfaces.

Clients must be aware of the differences between strategies to be able to select a proper one.

No need for functional programming.

Conclusion

We have just learned about the Strategy design pattern. If you need to handle family of many algorithms. You might consider using the Strategy design pattern.

If you have any ideas, few free to comment bellow. Thank you for joining with me. See you next time!


Đăng nhận xét

0 Nhận xét