8 Design Patterns EVERY Developer Should Know

NeetCode
6 Feb 202309:47

Summary

TLDRThis video delves into eight essential design patterns every developer should know, as outlined in the seminal book 'Design Patterns' by the Gang of Four. It covers creational patterns like Factory and Singleton, structural patterns such as Adapter and Facade, and behavioral patterns including Observer and Strategy. The script uses relatable examples, like ordering a burger or YouTube notifications, to explain these patterns, aiming to simplify complex programming concepts for better software design.

Takeaways

  • πŸ“š The video discusses eight essential design patterns from the book 'Design Patterns: Elements of Reusable Object-Oriented Software' by the 'Gang of Four'.
  • πŸ” The Factory pattern is likened to ordering a burger at a restaurant, where a factory class instantiates objects without exposing the instantiation logic to the client.
  • πŸ—οΈ The Builder pattern provides a step-by-step approach to object creation, allowing for more control over the construction process.
  • πŸ”’ The Singleton pattern ensures a class has only one instance and provides a global point of access to it, useful for maintaining a single copy of application state.
  • πŸ“’ The Observer pattern, also known as the pub-sub pattern, allows multiple objects to listen for and respond to events, as exemplified by YouTube notifying subscribers of new uploads.
  • πŸ”„ The Iterator pattern simplifies the way we traverse through elements of a collection without exposing its underlying representation.
  • πŸ› οΈ The Strategy pattern enables the dynamic selection of an algorithm from a family of algorithms, allowing behavior to be selected at runtime without modifying the class.
  • πŸ”Œ The Adapter pattern allows objects with incompatible interfaces to collaborate by converting the interface of one class into an interface expected by the clients.
  • 🎭 The Facade pattern provides a simplified interface to a complex subsystem, hiding the complexities behind a single, unified interface.
  • πŸ“ˆ The video emphasizes the importance of design patterns in software development, highlighting their relevance even in the rapidly changing landscape of JavaScript frameworks.
  • πŸ“˜ The presenter mentions a new course on object-oriented design patterns, including video lessons, written articles, and code examples in four programming languages.

Q & A

  • What are the three categories of design patterns introduced by the 'Gang of Four'?

    -The three categories of design patterns are creational patterns, structural patterns, and behavioral patterns.

  • What is the purpose of the Factory design pattern?

    -The Factory design pattern is used to create objects without exposing the instantiation logic to the client and refers to the newly created object using a common interface.

  • Can you explain the concept of the Builder pattern in the context of making a burger?

    -The Builder pattern allows for the construction of complex objects step by step. It provides a way to create a complex object by adding one part at a time, which can be useful when the construction process is complex and requires setting a lot of parameters.

  • What is a Singleton pattern and how is it used in an application?

    -The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. It is used for maintaining a single copy of an application state, such as tracking whether a user is logged in.

  • How does the Observer pattern, also known as the pub-sub pattern, work in the context of YouTube?

    -The Observer pattern allows multiple observers to listen for and respond to events. In the context of YouTube, the channel acts as the subject (publisher), and subscribers are the observers. When a new video is uploaded (event), all subscribers receive a notification.

  • What is the role of the Iterator pattern in programming?

    -The Iterator pattern provides a way to access the elements of an object sequentially without exposing its underlying representation. It is used to traverse complex data structures in a simple and consistent manner.

  • Can you describe the Strategy pattern and its benefits?

    -The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It allows the behavior of an object to be changed at runtime, following the open-closed principle, which states that software entities should be open for extension but closed for modification.

  • What is the Adapter pattern and how does it solve compatibility issues?

    -The Adapter pattern is a structural pattern that allows objects with incompatible interfaces to work together by wrapping their own interface around that of an existing class. It can be used to make a micro USB cable compatible with a standard USB port by using an adapter.

  • What does the Facade pattern conceal and why is it used?

    -The Facade pattern conceals the complex reality of a system's internal workings. It provides a simplified interface to a more complex subsystem, making the system easier to use and understand.

  • What is the significance of the book 'Design Patterns: Elements of Reusable Object-Oriented Software'?

    -The book, authored by the 'Gang of Four,' is significant as it introduced 23 fundamental object-oriented design patterns, which are still widely discussed and used in software development, demonstrating their enduring value.

  • How does the script relate the design patterns to everyday life examples, such as ordering a burger?

    -The script uses the example of ordering a burger to illustrate the Factory pattern, where you can order different types of burgers without worrying about the ingredients and assembly process, just like you would at a restaurant.

Outlines

00:00

πŸ”§ Design Patterns in Programming

This paragraph introduces the concept of design patterns, a fundamental topic in software development. It references the seminal work by the 'Gang of Four' from 1994, which introduced 23 object-oriented design patterns categorized into creational, structural, and behavioral patterns. The speaker humorously relates the longevity of this book to the rapidly changing landscape of JavaScript frameworks. The paragraph sets the stage for an exploration of eight design patterns, starting with the factory pattern, which is likened to ordering a burger without worrying about the ingredients. It also mentions the builder pattern for more control over object creation and the singleton pattern for ensuring a single instance of a class, using the example of application state in an app. The paragraph concludes with the observer pattern, which is compared to a publisher-subscriber model, using YouTube as an example to illustrate how subscribers receive notifications about new content.

05:02

πŸ”„ Iterator and Behavioral Patterns

The second paragraph delves into the iterator pattern, which defines a way to iterate over elements of an object without exposing its underlying structure. It contrasts simple iteration in Python with the need for a custom iterator for complex data structures like linked lists. The strategy pattern is then introduced, allowing for the dynamic alteration of an algorithm's behavior at runtime, exemplified by different filtering strategies for an array. The adapter pattern is described as a structural pattern that makes incompatible interfaces compatible, using the analogy of physical adapters like a USB to micro-USB converter. Finally, the facade pattern is introduced, which provides a simplified interface to a complex system, hiding the intricate details from the user. The paragraph ends with a plug for the speaker's object-oriented design interview course, which covers these patterns in more depth.

Mindmap

Keywords

πŸ’‘Factory

The factory pattern is a creational design pattern that provides an interface for creating objects without specifying their concrete classes. In the video, it is compared to ordering a burger, where the factory creates the burger for us based on the desired type, such as a cheeseburger or a vegan burger.

πŸ’‘Builder

The builder pattern is another creational design pattern that allows for constructing complex objects step by step. It provides more control over the construction process compared to the factory pattern. In the video, it's likened to assembling a burger by adding ingredients one at a time using a builder, which allows chaining methods for each ingredient and finally building the complete burger.

πŸ’‘Singleton

The singleton pattern ensures that a class has only one instance and provides a global point of access to it. This is useful for managing shared resources or application state. The video illustrates this with an application state that tracks whether a user is logged in, ensuring that only one instance of this state exists at any time.

πŸ’‘Observer

The observer pattern, also known as the pub-sub (publisher-subscriber) pattern, is a behavioral design pattern where an object (the subject) maintains a list of dependents (observers) and notifies them of any state changes. The video uses the example of YouTube, where subscribers receive notifications when a new video is uploaded by a channel they follow.

πŸ’‘Iterator

The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. The video explains this with an example of iterating through a linked list in Python, where a custom iterator helps traverse the list's elements easily.

πŸ’‘Strategy

The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This allows the algorithm to vary independently from clients that use it. In the video, it is exemplified by filtering an array using different strategies to remove either positive values or odd values.

πŸ’‘Adapter

The adapter pattern allows incompatible interfaces to work together by converting the interface of a class into another interface expected by the clients. The video gives the example of using a micro USB to USB adapter to connect a micro USB cable to a USB port, demonstrating how the adapter facilitates compatibility.

πŸ’‘Facade

The facade pattern provides a simplified interface to a complex subsystem, making it easier to use. The video describes it as a wrapper class that abstracts away lower-level details. An example is HTTP clients that hide the complexity of network operations, allowing programmers to use simpler interfaces.

πŸ’‘Creational Patterns

Creational patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The video mentions the factory, builder, and singleton patterns as examples of creational patterns that help manage the process of object creation in different ways.

πŸ’‘Behavioral Patterns

Behavioral patterns are design patterns that deal with object collaboration and delegation of responsibilities. They focus on how objects communicate and interact. The video discusses the observer and strategy patterns as examples of behavioral patterns that help manage object interactions and behavior.

πŸ’‘Structural Patterns

Structural patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities. These patterns focus on how classes and objects are composed to form larger structures. The video highlights the adapter and facade patterns as examples of structural patterns that help organize and simplify complex systems.

Highlights

Introduction to eight essential design patterns for developers.

The enduring relevance of the 'Design Patterns' book by the Gang of Four, even in the fast-paced JavaScript ecosystem.

Explanation of the Factory Pattern for object instantiation, akin to ordering a burger at a restaurant.

The Builder Pattern for constructing complex objects step by step, like adding ingredients to a burger.

The Singleton Pattern ensures a class has only one instance, useful for maintaining application state.

Observer Pattern, also known as pub-sub, for real-time updates across components, using YouTube as an example.

Iterator Pattern simplifies the iteration process over complex data structures like linked lists.

Strategy Pattern allows for dynamic behavior modification of a class through runtime strategy selection.

Adapter Pattern as a structural solution to interface incompatibilities, using USB cables as an analogy.

Facade Pattern hides complex system details behind a simple interface, making programming more manageable.

Practical implementation of the Observer Pattern with a YouTube channel and subscribers example.

Chaining methods in the Builder Pattern for fluent interface construction of objects.

Singleton Pattern's role in maintaining a single copy of application state with getAppState method.

The use of abstract classes or interfaces in the Observer Pattern to define subscriber behavior.

Strategy Pattern's adherence to the open-closed principle for extensible class behavior modification.

Adapter Pattern's practical use in making incompatible interfaces compatible, like micro-USB to USB.

Facade Pattern's concealment of complex realities, providing a simplified interface for programmers.

Introduction of an Object-Oriented Design Interview Course for further learning on design patterns.

Transcripts

play00:00

I heard you liked factories so I made

play00:02

you a factory inside a factory which

play00:04

inherits from an abstract Factory so it

play00:07

can create new factories but enough

play00:09

about programming in Java

play00:12

in this video we will learn about eight

play00:15

design patterns every developer should

play00:17

know in 1994 the gang of four released

play00:20

the holy book design patterns

play00:22

introducing 23 object-oriented design

play00:25

patterns falling into one of three

play00:27

buckets creational patterns structural

play00:30

patterns and behavioral patterns while

play00:33

some argue that it stated the fact that

play00:35

a 30 year old book is still being

play00:37

discussed definitely means something

play00:39

especially in a world where JavaScript

play00:42

Frameworks are going out of style faster

play00:44

than you can say JavaScript was a

play00:46

mistake anyways let's start with our

play00:48

first creational pattern the factory

play00:50

imagine that you want a burger but you

play00:53

don't want to have to worry about

play00:54

getting all the ingredients and putting

play00:56

them together so instead you just order

play00:59

a burger well we can do the same thing

play01:01

with code if it takes a list of

play01:03

ingredients to create a burger we can

play01:06

instead use a factory which will

play01:08

instantiate the burger for us and return

play01:11

it to us whether it's a cheeseburger a

play01:13

deluxe cheeseburger or even a vegan

play01:16

burger all we have to do is tell the

play01:18

factory what kind of burger we want just

play01:20

like you would do at a restaurant but be

play01:23

careful because this way you'll never

play01:24

know what's inside the Special Sauce we

play01:27

added a secret ingredient

play01:33

now alternatively if you want a little

play01:35

more control over how the sausage is

play01:38

made you can go with the builder pattern

play01:40

the idea is that if we want to make a

play01:43

burger we don't immediately have to pass

play01:45

in all the parameters we can use a

play01:47

burger Builder instead we'll have an

play01:50

individual method for adding each

play01:52

ingredient whether it's a bun Patty or

play01:55

cheese each one will return a reference

play01:57

to the Builder and finally we'll have a

play02:00

build method which will return the final

play02:02

product then we can instantiate a burger

play02:05

Builder add the Buns that we want the

play02:08

Patty that we want and the cheese that

play02:10

we want and we can chain these methods

play02:12

because remember each one will return a

play02:15

reference to the Builder finally we can

play02:17

build it and we have the exact burger

play02:20

that we want I've used this pattern a

play02:22

lot at Google with protocol buffers next

play02:25

we have the Singleton pattern and I'm

play02:27

not talking about my dating life a

play02:29

Singleton is just a class that can only

play02:32

have a single instance of it that's

play02:34

instantiated it has many use cases for

play02:37

example maintaining a single copy of our

play02:39

application stay we would start by

play02:42

having a static instance variable let's

play02:45

say in our app we want to know if a user

play02:47

is logged in or not but we won't use the

play02:50

Constructor to actually instantiate the

play02:52

application State we'll use a static

play02:55

method called get app stay which will

play02:58

first check if there's already an

play03:00

existing instance of our application

play03:01

stay if not we'll instantiate one if

play03:04

there already is though we'll just

play03:06

return the existing instance we'll never

play03:09

create more than one so now if we get

play03:11

our app State for the first time the

play03:14

logged in value will initially be false

play03:16

but if we get the app State again this

play03:18

will actually still be the first

play03:20

instance so if we modify the first

play03:23

instance and then print the logged in

play03:26

value for both of them they will both

play03:28

now be true this pattern can be useful

play03:30

so that multiple components in your app

play03:33

will have a a shared source of truth but

play03:36

how can all the components listen for

play03:38

updates in real time well that's where

play03:40

the Observer comes in our first

play03:42

behavioral pattern I prefer to call it

play03:45

the pub sub pattern it's widely used

play03:47

Beyond just object-oriented programming

play03:50

including in distributed systems let's

play03:53

take YouTube for example every time I

play03:56

upload a video all of my subscribers get

play03:59

a notification including you because

play04:01

you're subscribed right but in this case

play04:04

the YouTube channel is the subject AKA

play04:07

publisher which will be the source of

play04:10

events such as a new video being

play04:12

uploaded we might want multiple

play04:15

observers AKA subscribers to all be

play04:18

notified when these events happen in

play04:21

real time one way to implement this

play04:23

pattern is to have a YouTube channel

play04:25

class which maintains a list of its

play04:28

subscribers when a new user subscribes

play04:31

we add them to the list of subscribers

play04:33

when an event occurs we go through that

play04:36

list of subscribers and send the event

play04:39

data to each of them with a notification

play04:41

but we also have to define the

play04:44

subscriber interface which you can do

play04:46

with an abstract class or an interface

play04:48

different subscribers might implement

play04:50

this interface differently but for a

play04:52

YouTube user let's say that we just want

play04:54

to print the notification that was

play04:56

received so then we can create a YouTube

play04:59

channel add a few subscribers and we

play05:02

only have to call notify once and all of

play05:05

the subscribers will receive the

play05:06

notification this is also extensible

play05:09

enough that a subscriber could be

play05:11

subscribed to multiple channels an

play05:14

iterator is a pretty simple pattern that

play05:16

defines how the values in an object can

play05:19

be iterated through in Python just

play05:21

defining an array and then iterating

play05:24

through it with the in keyword uses the

play05:27

built-in list iterator this way we don't

play05:30

even have to index the array now for

play05:32

more complex objects like binary search

play05:35

trees or linked lists we can Define our

play05:38

own we can take a list node which just

play05:40

has a value and a next pointer and then

play05:43

a linked list which has a head pointer

play05:45

and a current pointer we can first

play05:47

Define the iterator with the inner

play05:49

function which will just set the current

play05:52

pointer to the head and then return a

play05:54

reference to the linked list to get the

play05:56

next value in the sequence we defined

play05:58

the next function if our current pointer

play06:01

is non-null we can get the value and

play06:04

then return it and also shift the

play06:06

current pointer but if we reach the end

play06:08

of the linked list we can send a signal

play06:11

that we're going to stop iterating to

play06:13

test it out we can just initialize the

play06:15

linked list and iterate through it with

play06:17

the in keyword this is a much more

play06:19

simple interface than having to actually

play06:21

update pointers ourselves now if you

play06:24

want to modify or extend the behavior of

play06:27

a class without directly changing it you

play06:30

can go with the strategy pattern for

play06:32

example we can filter an array by

play06:34

removing positive values or we could

play06:37

filter it by removing all odd values

play06:39

these are two strategies but maybe in

play06:42

the future we want to add more and we

play06:45

want to follow the open closed principle

play06:47

well we can define a filter strategy

play06:50

create an implementation which will

play06:53

remove all negative values and an

play06:55

implementation which will remove all odd

play06:58

values and then at run time we can pass

play07:01

this strategy into our values object and

play07:05

to test it out all we have to do is pass

play07:08

in the strategy into our filter method

play07:10

and we'll get our desired result this

play07:13

way we can add additional strategies

play07:16

without modifying our values class next

play07:19

we have the adapter our first structural

play07:22

pattern it's analogous to the real world

play07:25

where we have a screw that's too small

play07:28

to fit into a hole so instead we use an

play07:31

adapter which makes this screw

play07:34

compatible with the hole

play07:36

or maybe an example that you're more

play07:38

familiar with we have a USB cable and a

play07:41

USB port we can plug in the USB cable

play07:45

which will directly fit into the port

play07:47

but instead if we have a micro USB cable

play07:51

it's not compatible so instead we need a

play07:55

micro to USB adapter which extends from

play07:58

the USB clasp but is composed of a micro

play08:02

USB cable which will be plugged into the

play08:06

adapter we can override the plug USB

play08:09

method from our parent class if needed

play08:11

but it's not in this case and then we

play08:14

can plug our micro USB cable into the

play08:17

adapter and then plug it into the port

play08:19

and it works just like a regular USB

play08:22

cable and our last pattern is the facade

play08:26

according to the dictionary a facade is

play08:28

an outward appearance that is maintained

play08:31

to conceal a Less Pleasant or credible

play08:34

reality in the program programming world

play08:37

the outward appearance is the class or

play08:39

interface we interact with as

play08:42

programmers and the Less Pleasant

play08:44

reality is hopefully the complexity that

play08:47

is hidden from us so a facade is simply

play08:50

a rapper class that can be used to

play08:52

abstract lower level details that we

play08:55

don't want to have to worry about I'm

play08:57

surprised it even qualifies as a design

play09:00

pattern but some common examples might

play09:02

include HTTP clients that abstract away

play09:06

low-level Network details or even arrays

play09:10

yes a dynamic array like vectors in C

play09:13

plus plus or arraylists in Java are

play09:17

constantly being resized under the hood

play09:20

thankfully as programmers we rarely have

play09:22

to think about memory allocation though

play09:25

if you're interested to learn more check

play09:27

out my newly released object-oriented

play09:30

design interview course we tackle some

play09:32

popular interview questions I've

play09:34

included video less since written

play09:37

articles and code for four languages and

play09:40

I'll be sure to add additional lessons

play09:42

in the future thanks for watching and

play09:44

make sure to subscribe please

Rate This
β˜…
β˜…
β˜…
β˜…
β˜…

5.0 / 5 (0 votes)

Related Tags
Design PatternsObject-OrientedSoftware DevelopmentCreational PatternsBehavioral PatternsStructural PatternsSingleton PatternBuilder PatternObserver PatternIterator PatternStrategy PatternAdapter PatternFacade Pattern