Design patterns are great problem solving templates that developers can apply to their projects. There are way too many patterns to cover in a single article though and they tend to attack different needs. However, they can losely be categorized into three different groups, you have:

  • Your structural patterns, they deal with structuring the relationship between different components (or classes) and forming new structures in order to provide new functionalities. Examples of structural patterns are Composite, Adapter and Decorator.
  • Your behavioral patterns, they help abstract common behavior between components into a separate entity which in turn, and your creational patterns. Examples of behavioral patterns are Command, Strategy, and one of my personal favorites: the Observer pattern.
  • Your creational patterns, they focus on class instantiation and making your life easier in order to create new entities. I’m talking about Factory method, Singleton and Abstract Factory.

And although they can be implemented directly in JavaScript, specially now with ES6, the OOP approach that TypeScript takes makes it very simple and straightforward to follow generic guides (or even from other OOP languages) and gain all the benefits of these patterns (as opposed to having to work around some of the limitations vanilla JS has in regards to OOP).

Singleton

The singleton pattern is probably one of the most known design patterns out there. It is a creational pattern because it ensures that no matter how many times you try to instantiate a class, you’ll only have one instance available.

This is a great pattern to handle things such as database connections, since you’ll probably want to only handle one at a time, instead of having to re-connect on every user request.

//Simulate a database connectino class
	class MyDBConn{

	    protected static instance: MyDBConn | null = null
	    private id: number = 0

	    constructor() {
	        //... db connection logic
	        this.id = Math.random() //the ID could represent the actual connection to the db
	    }

	    public getID(): number {
	        return this.id
	    }

	    public static getInstance(): MyDBConn {
	        if(!MyDBConn.instance) {
	            MyDBConn.instance = new MyDBConn()
	        }
	        return MyDBConn.instance
	    }
	}

	const connections = [
	                        MyDBConn.getInstance(),
	                        MyDBConn.getInstance(),
	                        MyDBConn.getInstance(),
	                        MyDBConn.getInstance(),
	                        MyDBConn.getInstance()
	                ]

	connections.forEach( c => {
	    console.log(c.getID())
	})

Now, granted, you can’t directly instantiate the class, but with the getInstance method, you can be sure you won’t have more than one instance. In the above example, you can see how a fake class that would wrap the database connection would benefit from this pattern. Ths id property could easily be thought of as thee actual connection, and this little test is showing you how that “connection” is always going to be the same one, no matter how many times you call the getInstance method.

The output from this code is ofcourse:

0.4047087250990713
0.4047087250990713
0.4047087250990713
0.4047087250990713
0.4047087250990713

#javascript #web-development #design-patterns #typescript #programming

Design Patterns in TypeScript
6.85 GEEK