Introduction to Burger Delivery Application Design
Imagine managing a burger restaurant with a custom delivery app. Each burger type, beef, veggie, or chicken, is represented by a class. Initially, the app creates burger objects based on client orders, prepares them, and returns the result.
Challenges with Initial Implementation
- Concrete burger classes (BeefBurger, VeggieBurger) differ and do not share a common interface initially.
- Method returning burger objects is limited to a single type, hindering flexibility.
- Adding new burger types requires modifying existing code, violating the Open-Closed Principle.
- Duplication of burger creation logic leads to maintenance challenges.
Introducing a Common Base Class
Creating an abstract Burger class or interface to unify common behaviors:
- Allows the method to return a unified type.
- Simplifies code by moving shared methods into the base class.
Limitations and Need for Encapsulation
- The
orderBurgermethod remains open for modification when new burger types are added. - Introducing if-statements for each new burger violates the Single Responsibility Principle.
Simple Factory Idiom
- Encapsulate burger creation into a single
BurgerFactoryclass. - Factory's sole responsibility is creating burger objects.
orderBurgercalls the factory, passing burger type to get the correct burger object.- Centralizes creation logic and isolates concrete burger types within the factory.
Why Simple Factory Is Not a Full Pattern
- Factory still requires modification to add new burger types (adding if-conditions).
- Does not fully adhere to the Open-Closed Principle.
Transition to Factory Method Design Pattern
Key Concepts:
- Move burger creation back to an abstract
Restaurantclass. - Define an abstract factory method
createBurger()to be implemented by subclasses. - Subclasses like
BeefBurgerRestaurantandVeggieBurgerRestaurantdecide which burger to instantiate. - The
orderBurgermethod uses this factory method to obtain the burger, decoupling from concrete types.
Benefits:
- Delegates object creation to subclasses, enabling extensibility.
- Adheres to SOLID principles, especially Open-Closed and Single Responsibility.
- Promotes scalability: new burger types mean just adding new subclasses without changing existing code.
UML Class Diagram Overview
- Product interface: Burger
- Concrete Products: BeefBurger, VeggieBurger
- Creator class: Abstract
Restaurantwith factory method - Concrete Creators: Subclasses implementing
createBurger()for specific burger types
When to Use the Factory Method Pattern
- Unknown exact types at compile time
- Need for extending product types independently
- Desire to centralize creation logic and reduce code coupling
Real-World Extension Scenario
- Opening a new Italian-style restaurant delivering the same burgers but prepared differently.
- Adding new creation logic inside existing factories would again violate Open-Closed Principle.
- This scenario motivates more advanced patterns like the Understanding 7 Essential Software Design Patterns (covered in next video).
Conclusion
The Factory Method pattern organizes code to create products flexibly and maintainably, ideal for applications like burger delivery systems. It supports clean extensions and adheres to key software design principles, ensuring the app remains robust as the menu grows and changes.
For a deeper understanding of evolving application architectures, consider exploring Understanding Hexagonal Architecture: Transforming MVC Applications, which complements the scalability and maintainability goals discussed here.
What's up geeks and welcome to the channel! Imagine you have a burgers restaurant and for this restaurant you created a delivery application that delivers burgers Now if each type of burger we deliver is represented by a class
then the code backing the delivery and production of these burgers can be written as follows after receiving our client request our application will identify the food it needs to prepare and based on this information it will proceed by creating the
object corresponding to this type of burger, prepare it, and then return it to the user however you see there's a slight limitation here as the BeefBurger and VeggieBurger objects you are creating represent different types of products and the method we are implementing here can
only return a single type a single object therefore if these products do not have a common base class or interface we won't be able to proceed with such an implementation So let's create a base class for our products and try to use it within the code of our application
this class will be the Burger class Now on top of abstracting our two products into a single class, what we can also do is extract the common behaviors of these products to this class as they are already implementing them
Okay our application looks complete now but when we see code like this we know that when things change like if we add new recipes to our delivery menu or more products to our restaurant we're going to have to open
this code and change it and that violates our open-closed and single responsibility principles We'll also end up writing the same piece of code in several places in the app making things even worse
So what do we do? Well let's look at what varies and encapsulate it! When our restaurant grows and changes over time we are going to add and remove recipes from the menu So in the second version of our app we removed the veggie burger and added the chicken burger option
you can clearly see that the variety of food we can deliver is getting in the way of closing this code for modification and as long as our restaurant is open this code is going to remain open To fix this what we do is take our
burger's creation code and encapsulate it, separate it into a class called a Factory. Why a factory? because this is a class whose sole responsibility is creating burgers, it's a burger factory. Now anytime we want to order something
from our restaurant we'll call this method, pass it a type, and after figuring it out, the method will return the requested order for us that implements the Burger class Now all this code is in one place nicely
separated from the rest of the restaurant code and to integrate it back in our original method what we have to do is create a factory object pass to it the type and boom our food is ready our orderBurger method no longer has to worry about the concrete type of the burger requested
because whatever it is we know that it will implement the Burger interface and that's all we care about. We call this design the Simple Factory Idiom and our example can be represented by the class diagram you see in front of you
it starts with the client of the factory in our case the Restaurant class itself then we have our Factory which is the only place where the concrete type of burgers is known and then we have our concrete products, the burgers our restaurant
delivers via the app we are implementing, all concrete products must implement the same interface or abstract product. Now, one thing to note is that the simple factory we've been discussing since the beginning of this video
is not a full-fledged official pattern it is more of an idiom that's commonly used however it is the first step in understanding one of the most powerful design patterns out there: The Factory Method Design Pattern. This pattern is a creational design pattern,
it loosens the coupling of a given code by separating the product's construction code from the code that uses this product. In our previous example the product was the burgers we are delivering. So let us go back to this example to
try and see together why the implementation we did isn't considered a full-fledged design pattern. When we encapsulated the creation logic of our burger in the simple factory class we isolated this logic and created a class whose sole purpose is creating burger objects
by doing this we followed the single responsibility principle and that's great! However if you look closely you will see that this class on its own is still open for modification and when we add more recipes to our menu we will have to add if-statements to this method
and one way to fix this is by applying the factory method design pattern. To do that let's remove our simple factory class and put back the creation logic and the orderBurger method inside the Restaurant class to start from scratch.
Okay, the first thing we need to do is abstract the restaurant class why are we doing that? Well it's because the createBurger method that used to exist in the simple factory we had will now become an abstract method inside
the Restaurant class this method is the factory method and will be implemented by the sub-classes of the restaurant class in this example and based on the burgers we are delivering these subclasses will
be the BeefBurgerRestaurant and the VeggieBurgerRestaurant You see that is actually how you pinpoint the usage of a factory in a given code as the factory method design pattern relies heavily on inheritance
it delegates objects creation to subclasses that implement the factory method. So after defining an interface for our products in this case the Burger interface we let creator subclasses decide which class to instantiate
and that is exactly what we are doing in this implementation. Okay now all that is left to do is replace the creation code inside our business logic or the orderBurger method with the factory method Notice that the orderBurger method is no longer
dependent on the request object and that's because we don't need it as the users of our restaurant can now directly instantiate and invoke the concrete restaurant class implementation they need and the correct prepared burger will
be returned to them. Now I want you to take a look at the structure of the factory method pattern represented using a UML class diagram as you may encounter it while going through different references.
Let's try to relate this structure to our delivery application example the Product interface and the ConcreteProducts obviously represent the burger classes in our example The Creator class however, the one
housing the factory method, was represented using the restaurant class in our example And finally the concrete creators are represented by the different restaurant classes in which the creation process of our burgers is defined. Okay now you know how to implement
the factory method pattern but when should you use this pattern? should you apply it on all parts of your application that have to do with creation stuff? Well if you have no idea beforehand of the exact types and dependencies
of the objects your code will work with then it is probably a hint that you should make use of this pattern right from the beginning as the factory method makes it easy to extend the product construction code independently from the rest of the application
and hence allows you to introduce new types of products into the program without breaking existent client code by doing this you wouldn't only be providing the users of your application with a way to extend its internal components
but also and most importantly you will be following and applying the open-closed principle and the single responsibility principle as you are centralizing the product creation code in one place in the program. Now before ending the video I want you
to imagine that your burger business boomed and you decided to open another restaurant. This restaurant will deliver the same burgers you have however this one will prepare them the Italian way.
Great news right? but what about the delivery application and the factory method design pattern we used? Adding the Italian option inside the implementations of the abstract factory method will lead to something like this
you can clearly see that this code is kinda open for modification right? and on top of this we now have the need to be dependent again on the request object provided to us by the client but how could our code break even
though we are applying the factory method pattern? This question will be answered in the next video of this series: The Abstract Factory Pattern. So that's it for this video, I hope it was helpful, thank you guys for watching, take care and I will see you in the next one!
The initial approach has concrete burger classes without a common interface, returns objects of a single type, and requires modifying existing code to add new burger types, which violates the Open-Closed Principle and leads to duplicated creation logic.
Creating an abstract Burger class or interface unifies shared behaviors, allows methods to return a common type, and reduces code duplication by centralizing common functionality, making the design more consistent and easier to extend.
The Simple Factory centralizes object creation but still requires modifying the factory to add new burger types (using if-statements), thus it does not fully adhere to the Open-Closed Principle and can become harder to maintain as the number of burger types grows.
Factory Method defines an abstract createBurger() method in the Restaurant class, letting subclasses decide which burger to instantiate. This delegates creation to subclasses, enables easy extension by adding new restaurants without modifying existing code, and adheres to SOLID principles.
Use the Factory Method pattern when the exact product types are unknown at compile time, you want to extend product types independently, and you need to centralize creation logic while minimizing code coupling to enable scalability and maintainability.
It allows new burger types to be added by creating new subclasses of Restaurant that implement createBurger(), avoiding changes to existing code and ensuring the system is open for extension but closed for modification.
Consider exploring advanced design patterns and architectures, such as hexagonal architecture or other essential software design patterns, to further enhance scalability and maintainability as your application grows complex and requirements evolve.
Keep this summary
Save it to LunaNotes and it becomes a real note in your library — editable, searchable, and ready to turn into flashcards or a diagram. Free to start.
Save to LunaNotesOr summarise for another video.
This summary and transcript were automatically generated using AI with the Free YouTube Transcript Summary Tool by LunaNotes.
Related summaries
Scalable System Design Explained Using a Restaurant Analogy
Explore how building a scalable, resilient system parallels running a growing pizza parlor. This guide covers vertical and horizontal scaling, fault tolerance, microservices, load balancing, and decoupling with real-world examples to simplify complex technical concepts.
Understanding 7 Essential Software Design Patterns
Learn about 7 critical software design patterns that improve your programming skills. Discover how to effectively implement them!
Understanding Hexagonal Architecture: Transforming MVC Applications
In this engaging live session, we explore the principles of hexagonal architecture and its advantages over traditional MVC applications. The discussion includes real-world examples, challenges faced during the transition, and the importance of maintaining a clear separation between business logic and presentation layers.
Building the Ultimate Auto Space Parking Application
Learn how to create an advanced parking application with Auto Space using modern technologies.
Mastering the Lean Startup Approach: Your Guide to Successful Entrepreneurship
Learn how to apply the Lean Startup principle for sustainable business success with practical insights and examples.
Most viewed summaries
A Comprehensive Guide to Using Stable Diffusion Forge UI
Explore the Stable Diffusion Forge UI, customizable settings, models, and more to enhance your image generation experience.
Kolonyalismo at Imperyalismo: Ang Kasaysayan ng Pagsakop sa Pilipinas
Tuklasin ang kasaysayan ng kolonyalismo at imperyalismo sa Pilipinas sa pamamagitan ni Ferdinand Magellan.
Mastering Inpainting with Stable Diffusion: Fix Mistakes and Enhance Your Images
Learn to fix mistakes and enhance images with Stable Diffusion's inpainting features effectively.
Pamamaraan at Patakarang Kolonyal ng mga Espanyol sa Pilipinas
Tuklasin ang mga pamamaraan at patakaran ng mga Espanyol sa Pilipinas, at ang epekto nito sa mga Pilipino.
How to Install and Configure Forge: A New Stable Diffusion Web UI
Learn to install and configure the new Forge web UI for Stable Diffusion, with tips on models and settings.
Found this summary useful?
Take it with you. One click puts it in your own LunaNotes library.
Save to LunaNotes