Design Patterns: Make your code modular
Tags: designpatterns, webdev, tutorial, programming
Published: 2023-04-08 09:48:38

> Whenever we start learning to code, Either we start from solving Data structures and Algorithms problems or We start from web development. It varies person to person, But one thing that most of us ignore is:- **Design Patterns**

![Design Patterns](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mtaa4j3bcavb0uxjytk.png)

_Yes, It is right you will end up changing code too frequent if you haven't thought about the design at the start._

Always Remember, Software Development is 50% Solutionising, 30% Debugging and 20% Coding. While Solutionising first priority will always be modular, well designed and loosely coupled code.

➪ Today we'll dive deeper into the design patterns that can be followed while coding.

## 📌 Strategy Design Pattern
------

This pattern suggests that when a class does a thing in so many different ways then you can take those all different things/algorithms and make them different strategies.

Example:- Let say you own a Map app where you suggest path from A to B via Vehicle only. But now in v2 release you want to add walk and public transport also. So, in our Navigator we can use different strategies to navigate i.e.

- Walk
- Vehicle
- Public Transport

These different strategies can be combined in an interface as:-

![Strategy pattern](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sj6rrwj1sbj65s63gtew.png)
Image Reference:- [Refactoring Guru](https://refactoring.guru/design-patterns/strategy)

> Navigator "has-a" relationship with Route Strategy which means It contains a RouteStrategy Interface. Road Strategy, PublicTransport Strategy and Walking Strategy "is-a" relationship with RouteStrategy.

Dont't worry we'll dive deeper in the code:- 

```JAVA
public interface RouteStrategy{
    public void buildRoot(int x1, int x2, int y1, int y2);
}

public class RoadStrategy implements RouteStrategy{
    @Override
    public void buildRoot(int x1, int x2, int y1, int y2){
        // Build root via Road
    }
}

public class PublicTransportStrategy implements RouteStrategy{
    @Override
    public void buildRoot(int x1, int x2, int y1, int y2){
        // Build root via Public Transport
    }
}

public class WalkingStrategy implements RouteStrategy{ // is-a relationship with RouteStrategy
    @Override
    public void buildRoot(int x1, int x2, int y1, int y2){
        // Build root via Public Walk
    }
}

public class Navigator{
    private RouteStrategy routeStrategy; // has-a relationship with RouteStrategy
    
    public Navigator(RouteStrategy routeStrategy){
        this.routeStrategy = routeStrategy;
    }

    public void buildRoot(int x1, int x2, int y1, int y2){
        routeStrategy.buildRoot(x1, x2, y1, y2);
    }

}
```

## 📌 Observer Design Pattern
-----

This pattern is kind of subscription based or observing someone.

![Observer Design Pattern](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67odvbj6qfgqa5e6q5sm.png)
Image Reference:- [Refactoring Guru](https://refactoring.guru/design-patterns/observer)

Let say when you go on amazon and wanted to buy a "T-shirt" but that particular one is out of stock. Then, what you do is you click on **Notify me** when available. So, there you are doing nothing but creating an observer that will keep observing once the stock will be available.

![Out of stock](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpw3vd0s7fsx6qu1q27f.png)
> Flipkart out of stock, Notify me button

![Observer Design Pattern](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccm8jvbvexuu3b8f9l1j.png)
Image Reference:- [Refactoring Guru](https://refactoring.guru/design-patterns/observer)

> Now, whenever something will happen inside the Publisher it will notify its subscribers that can further take different actions like sending a notification to a user.

These Publishers and Subscribers are also known as Observables and Observers respectively.

```JAVA
import java.util.ArrayList;

public interface ProductNotifyObserver{ 
// Subscribers Interface
    public void update(Object o);
}

public class SmartPhonesNotify implements ProductNotifyObserver{ 
// Smartphone specific observer
    private String userId;
    private String productId;
    
    @Override
    public void update(Object o){
        this.userId = o.getUserId;
        this.productId = o.getProductId;
        // Call notify service to send a notification to the user
    }
}

public class ProductNotifyObservable{ 
// Publisher or Observable
    List<ProductNotifyObserver> observables = new ArrayList();

    public void addProduct(ProductNotifyObserver p){ 
// user is clicking on Notify-me button and we add that Product into our list
        this.observables.add(p);
    }
    public void removeProduct(ProductNotifyObserver p){
        this.observables.remove(p);
    }
    public void setProduct(Product product){ // product gets back in stock
        for(ProductNotifyObservable p : this.observables){
            if(p.getProductId == product.getProductId){
                p.update(product);
            }
        }
    }
}
```

So, referring to the above pseudo code, It is clear that whenever a product comes back in stock. We can call the observable **setProduct(Product p)** that will call all the observers that are specific to that product only (Observers are the users clicked on notify me) will trigger the update() method of that specific observer only.

📌 This is it for today, In part 2 we will cover design patterns like Decorator and Factory. Follow for more such in depth content.

Follow on 🐥 [Twitter](https://twitter.com/AlphaDecodeX) for more updates and daily learnings