
This video shows the entire overview of the course.
SOLID principles can upgrade the code someone writes. The problem is, they are complex.
Describe what SOLID means
Brief summary of all principles
It’s fairly common for developers to write classes that do more than one thing.
Demonstrate a method that besides its main task, it also tackles error handling and HTML
Refactor the method to adhere to the Single Responsibility principle
The Open/Closed principle is rarely used as developers keep adding stuff to their classes.
Describe what “Closed to modification” means
Explain what “Open to extension” means
Demonstrate a comprehensive example
The Liskov Substitution Principle is perhaps the hardest of the five. We need to provide a high quality explanation without making the video long and boring.
Theoretical examination
Use a “Quiz App” example
According to the Interface Segregation principle, a class shouldn’t be forced to implement a method that it does not need or can’t implement.
Create an ISmartDevice interface
Implement it in a phone
Show how a tablet can’t implement all the methods and therefore needs segregation
Dependency Inversion is so vital that a part of it, Dependency Injection will have its own section. But for now we need to demonstrate how important it is.
Explain Dependency Inversion and loose coupling in theory
Demonstrate tight coupling’s downsizes
Implement a service the correct way by connecting to an abstraction
In the previous section, we only talked about principles. We did not mention patterns. In this one we will work almost exclusively with them so introductions are in order.
Describe design patterns in general
Briefly explain each creational pattern that we are going to study
Sometimes we need to only have a single instance of a class.
Describe singleton theoretically
Implement a Singleton TypeScript class for keeping up stats
Following the single responsibility principle, our consumer classes shouldn’t be the ones responsible for knowing how to instantiate classes that we need.
Describe the factory pattern in theory
Create a GameCharacterFactory class
Although not a pattern itself, loose coupling is very important and understanding it is critical to anyone willing to learn design patterns.
Describe loose coupling
Show examples of how the extended use of interfaces helps with loosely coupled code
The object pool is a great pattern to avoid having to be constantly initializing our enemy classes every time we need them.
Use the factory created in the previous video
Extend it to work with an object pool
Not all TypeScript developers are familiar with Dependency Injection and since we are dedicating a whole section on it we better spend a video trying to explain the most interesting topics.
Explain Dependency Injection thoroughly
Show a very simplistic visual example
There’s great value in creating a custom IoC container. The viewer will get to understand the inner workings of Dependency Injection.
Describe the vital operations that an IoC container needs to be doing
Implement the registration method
Implement the dependency resolution method
Decorators are an experimental TypeScript feature with strong chances of being included in next JavaScript versions as well. It also comes in handy with DI implementations.
Introduce method decorators
Introduce decorator factories
Introduce class decorators
We can use decorators to enhance our DI container implementation.
Create a “register” class decorator
Replace all calls to the register method with the register class decorator
Creating a custom DI container is great for educational purposes for real world apps we shouldn’t use a container we built in an hour’s time.
Introduce the InversifyJS container
Register dependencies with InversifyJS
Create classes that will have their dependencies resolved using InversifyJS
Sometimes we need to combine entities into mixins but only dynamically on runtime. Here’s where the decorator pattern comes in.
Display an example of bad inheritance practice
Create a decorator hierarchy of a computer system and its subsystems
Demonstrate a test with a server computer being combined with two decorators
In cases where we need to connect different APIs we need a way to avoid having to rewrite all the code.
Describe the issue with having to replace a CountriesRepository
Introduce the new Countries Service
Create an adapter and solve the problem
In cases where we need to connect different APIs we need a way to avoid having to rewrite all the code.
Use the adapter to implement a new repository
Test the new repository
We need to create a central class that will act as a bridge between our client application and a 3rd party library and service.
Use a very comprehensive example of the MailChimp API
Introduce a JSON Placeholder service
Implement a facade
We need a way to create part-whole collections.
Describe an example of decks of cards
Create an ICardComponent interface
Implement it in both the card class and the CardDeck class
Sometimes we are looking for a way to swap similar algorithms at run time
Describe the problem
Present the strategy pattern
Implement a Strategy Pattern demo using an error handler example
Watching for property changes is vital especially in a world of applications with high demand for constant responsiveness
Create a car class and watch its current speed property
Create two observer functions and register them
Inspect the console for property changes
The Command Pattern allows the encapsulation of a whole process. We need it if we are to run a process later in time or even undo it
Introduce the concept of a worker process
Delegate error logging to a worker process
The template method will help us create subclasses that implement parts of an already defined process
Describe the problem of having multiple subscription plans in your SaaS application
Solve the issue by creating a template base class
Create two profile subclasses that implement the steps differently
Following a similar path like the previous video. We need a way to change subscription status. The state pattern is perfect for such a feat
Define a state interface
Define concrete states
Define the context class and change states
In programming, there are several problems that occur frequently. To solve these problems, there are various repeatable solutions; these are known as design patterns. Design patterns are a great way to improve the efficiency of your programs and improve your productivity; you'll learn them all in this course. This course is a collection of the most important patterns you need to improve application performance and productivity.
This course starts by exploring SOLID principles to write clean code. Then you will create new objects and instance of classes with creational design Patterns. Next, you will utilize dependency injection with InversifyJS to create testable, maintainable, and extensible code.
Moving on, you will explore structural design patterns to better express the relationships between different application entities. Lastly, you will investigate behavioral patterns to add flow to your applications and add levels of communication between your entities.
About the Author
Dimitris Loukas is a software engineer currently working with Angular, Node .js, and Docker for a referral marketing startup. He is also developing trading software applications using C# and Aurelia. He has worked for two startups in the past, is active in the open source community, and loves taking up small side-projects. He has developed microservices using C# and Node .js and has also mastered Angular, Aurelia, and Vue .js.. He was an early adopter of .NET Core and is fascinated by modern JavaScript and where the web is going.