when you first become a junior developer your code will look like Playdoh snakes but as you progress to senior developer and learn about software design patterns your code will look like the cysteine chapel but when you then progress to principal engineer you'll realize that nobody wants to maintain the cine Chapel for a silly website and go back to making Play-Doh snakes in today's video you'll learn about 10 different software design patterns along with the pros and cons of using them which can be very subjective and controversial one of the most influential books in the history
of programming is design patterns by four C++ Engineers called The Gang of four it breaks down 23 different approaches to address recurring problems that programmers face which are categorized as creational patterns how objects are created structural patterns how objects relate to each other and behavioral patterns how objects communicate with each other becoming a proficient software engineer is not about memorizing the syntax of a programming language but rather the ability to solve problems with it by the end of this video you'll understand a variety of different patterns for solving problems as they relate to Modern app
developers before we get started I want to give a big shout out to refactoring doguru they gave me permission to use some of their Graphics that explain design patterns better than anything else out there they're based in Ukraine and it's seriously one of the coolest programming websites on the internet design patterns are really interesting because they're not just like algorithms that you can copy and paste from stack Overflow you actually need to use your brain to implement them it can be tempting to implement them all over the place but when used improperly they can add
additional complexity and boilerplate to a code basee the book is not the Bible and there are many criticisms of it regardless knowing how to write recognized design patterns will help you level up as a programmer the first pattern we'll look at is Singleton which is very easy to understand it's a type of object that can only be instantiated once in typescript we might Implement a Singleton class called settings to represent the global app settings data we'll give it a static instance property and then make its Constructor private so that it cannot be instantiated with the
new keyword we then create a static get instance method that will check to see if the instance has already been created and if not it will create a new one and that ensures that only one object can be created that's great and all but here's where things become a little more nuanced in JavaScript we have object literals and also the concept of global data and objects are passed around by reference we get all the same basic characteristics as this pattern by simply creating a global object the pattern itself is really just extra boiler plate that
we don't need it's an entirely different story in C++ but the moral is to lean on your languages built-in features before implementing a fancy design pattern now let's take a look at the Prototype pattern which is just a fancy word for clone if you've done object oriented programming you should be familiar with inheritance where a class can be extended with a subclass one problem with inheritance is that it can lead to a complex hierarchy of code the Prototype pattern is an alternative way to implement inheritance but instead of inheriting functionality from a class it comes
from an object that's already been created this creates a flat prototype chain that makes it much easier to share functionality between objects especially in a dynamic language like JavaScript which supports prototypal inheritance out of the box imagine we have an object named zombie this is our prototyp type but now we want to create a new object based on it that also has a name we can do that with object create by passing the zombie as the Prototype then specify additional properties like name for the new object the interesting thing is that if you log this
object you'll only see the name and not the eat brain's method however if you try to call that method it will still work that's because JavaScript will go up the Prototype chain until it reaches the root looking for any methods or properties on the parent objects you can always get the Prototype from an object by using this Proto property however that's not a modern best practice and instead you should use object get prototype of now when it comes to classes in JavaScript prototype refers to its Constructor and that means that we can extend a class
with additional functions if we want to however that's also generally considered a bad practice now let's switch gears to the Builder pattern imagine you're running a hot dog stand and when a customer places an order they need to tell you everything they want in the sandwich and the Constructor that works but it's kind of hard to keep track of all these options and we might want to defer each step to a later point with the builder pattern we create the object step by step using methods rather than the Constructor and we could even delegate the
building logic to an entirely different class in JavaScript We'll have each method return this which is a reference to the object instance that allows us to implement method chaining where we instantiate an object then chain methods to it but always get the object as the return value you'll come across this pattern frequently with libraries like jQuery but it's gone a bit out of style in recent years another pattern you may come across is Factory instead of using the new keyword to instantiate an object you use a function or method to do it for you that
may sound trivial but here's a practical example let's imagine we're building a crossplatform app that runs on both IOS and Android they both have the same interface but in our code we're doing a bunch of conditional checking to determine which button to show that's not very maintainable instead we can create a subass or function that will determine which object to instantiate now instead of repeating the same logic we use the factory to determine which button should be rendered now we're ready to look at the first structural pattern facade a facade is the face of a
building inside that building there's all kinds of shenanigans corruption and complexity that the end user doesn't need to know about a facade is basically just a simplified API to hide other low-level details in your code base let's imagine we have classes for the plumbing system and electrical system and inside of them we have all kinds of complex stuff going on like pressure and voltage the people living in the house don't need access to these low-level details so we create a facade class that contains the low-l systems as dependencies but then simplifies their operation like we
might combine all the electrical and plumbing details into a single method so the end user can simply turn them on or off with a single method almost every package that you install with JavaScript could be considered a facade in some way like jQuery is a great example of a facade for the more annoying low-level JavaScript features the next structural pattern we'll look at is proxy which is just a fancy word for a substitute like in school you might have a substitute teacher to replace the real thing in programming you can replace a Target object with
a proxy but why would you ever want to do that well well a great case study is the reactivity system in vue.js in view you create data but the framework itself needs a way to intercept that data and update the UI whenever that data changes the way view handles that is by replacing the original object with a proxy a proxy takes the original object as the first argument then a Handler as the second argument inside of which we can override methods like get and set which allows us to run code whenever a property is accessed
on the object or changed for example inside of set we might tell the framework to render use reflect to update the data on the original object the end user can now work with the proxy just like the original object but it can trigger the side effects behind the scenes proxies are also commonly used when you have a very large object that would be expensive to duplicate in memory and now we're ready to look at some behavioral patterns starting with iterator the iterator pattern allows you to Traverse through a collection of objects modern languages already provide
abstractions for the iterator pattern like the for Loop when you Loop over an array of items you're using the iterator pattern but one thing that really chaps my ass about JavaScript is that there's no built-in range function what I wish I could do is easily iterate 10 times at a certain interval we can actually do that fairly easily by implementing our own iterator pattern in JavaScript you can do that by defining an object that has a next method on it that function needs to return an object that has a value which would be the current
value in the loop and a done property so it knows when to finish iterating in this case we will keep moving on to the next step if the start value is less than the end value but for each iteration we will increment the start value with a step eventually the start will be greater than the end at which point we can return an object with the done property as true and that tells JavaScript to stop iterating now a cool technique here is that we can add symbol iterator to this object which allows us to use
it in a regular four of loop at the end of the day with iteration you start with a collection and then write some code that determines how to get from the beginning to the end it's a pole-based system unlike the next pattern we'll look at Observer which is a push based system The Observer pattern allows many objects to subscribe to events that are broadcast by another object it's a on to many relationship in the real world you might have a radio tower that sends out a signal then a bunch of receivers who listen in at
the same time this pattern is used all over the place in app development like in Firebase when your data changes on the server all your client apps are subscribed to it and automatically updated with the latest data in our code here I'm going to bring in the rxjs library to simplify the demonstration of this pattern it provides a subject class which is the data that we want to listen to now once we have a subject we can add multiple subscriptions to it the subject will keep track of all these subscriptions and call their callback functions
whenever the data changes experiment with this pattern right now by clicking like And subscribe on this video now at some later point we can call the next method to push a new value to the subject whenever that happens every subscription will be notified personally I like to think of this as a loop that unfolds over the dimension of time but now let's move on to the mediator pattern a mediator is like a middleman or broker imagine we have a class for airplane and Runway we might have multiple runways and multiple airplanes and somehow we need
to figure out if an airplane is clear to land on a given Runway currently to do that all these objects would have to communicate with each other we have a many to many relationship that's very dangerous both in real life and in programming a solution is to create a mediator like an air traffic controller that sits between the runways and the airplanes to provide coordination and communication here's a more prac iCal example in the expressjs web framework there is a middleware system you have incoming requests and outgoing responses middleware sits in the middle by intercepting
every request like an airplane and transforms it into the proper format for the response the runway it provides a separation of concerns and eliminates code duplication and that brings us to our 10th and final design pattern state where an object behaves differently based on a finite number of states in your code you've likely Ed conditional logic or switch statements to handle a bunch of different possibili ities based on the state or data in your application code like this generally doesn't scale very well the state pattern allows you to start with one base class then provide
it with different functionality based on its internal State the idea is related to finite State machines in libraries like xstate where the goal is to make an object's Behavior predictable based on its underlying state in this example we have a human class that will think something different based on its mood currently we're doing that with a switch statement but another way to go about it would be to create a separate class class for each possible State inside each class we will have an identical method that behaves differently now in the human class we set the
state as a property and whenever that method is called we delegate it to its current state that means whenever the state changes the object will behave in a completely different way but at the same time we don't have to change the API or use a bunch of conditional logic I'm going to keep things simple and wrap it up there but remember there are a bunch of other designed patterns out there to learn become a PR member at fireship iio to learn how to apply patterns like this in real applications thanks for watching and I will
see you in the next one