Creating objects which are flexible, scalable, and easy to maintain is quite challenging in the world of software development and a lot of problems come from that area. That’s a reason why developers came up with software design patterns, creational patterns in particular, which aim to provide a list of the best practices to solve issues related to object creation and maintain the software for as long as possible.
In this post, we’ll take an in-depth look at the factory design pattern in dart which is a creational pattern that ensures creating objects at ease. You’ll be able to understand what is factory method, when and why to use, practice an example, and see its pros and cons.
Table of Contents
- What is Factory Design Pattern?
- Factory Method Example in Dart
- When to Use the Factory Method?
- Why Do We Use Factory Method Design Pattern?
- Conclusion
What is Factory Design Pattern?
According to the book of “Design Patterns Elements of Reusable Object-Oriented Software”, Factory method is to define an interface to create an object, but let the subclass decide which class to instantiate. Factory method lets a class defer instantiation to sub-classes.
But what does that mean? The Factory Method pattern can be thought of as a chef in a restaurant. The chef has a set of ingredients and recipes to create different dishes, just as the Factory Method has a set of classes and methods to create various objects. The chef creates dishes in a centralized and consistent manner based on certain ingredients, and the Factory Method creates objects in a centralized and consistent manner based on specific characteristics. The dishes are like the objects created, and the ingredients and recipes are like the abstract classes and methods used in the Factory Method pattern. The chef represents the factory class and their ability to create various dishes represents the Factory Method’s ability to create various objects.

The Factory Method pattern is a creational design pattern that provides an interface for creating objects in a super-class, but allows sub-classes to alter the type of objects that will be created. We don’t have interfaces in dart but we have abstract classes which work the same way. The Factory pattern provides a mechanism to delegate object creation to sub-classes, rather than creating objects the normal way directly within the super-class.
Now, the factory method consists of three main components:
- Abstract base class: this class acts as an interface to create objects but doesn’t provide a concrete implementation. It kinda defines the main structure of the object but doesn’t implement its feature.
- Concrete sub-classes: these are the classes that provide the concrete implementation of the interface defined in the abstract base class. They create objects of specific types that are fully implemented.
- Factory class: this is a factory constructor that’s responsible for creating the objects. It acts as an intermediate that uses the abstract base class to define the interface for object creation, and delegates the actual object creation to the concrete sub-classes.

Factory Method Example in Dart
Let’s consider a simple example to illustrate the factory method pattern using the chef analogy. We’ll create a factory that creates dishes, such as pizza and spaghetti. The abstract base class will define the interface for creating the dishes, while the concrete sub-classes will provide the actual implementation of dish creation.
Abstract base class
abstract class Dish { String name; Dish (this.name); void cook(); }
Concrete subclasses
class Pizza extends Dish { Pizza(super.name); @override void cook() { print('Cook $name Pizza'); } } class Spaghetti extends Dish { Spaghetti(super.name); @override void cook() { print('Cook Spaghetti'); } } class RoastedChicken extends Dish { RoastedChicken(super.name); @override void cook() { print('Cook Roasted Chicken'); } }
Factory class
class DishFactory{ static Dish createDish(String type, String name) { switch(type) { case 'Pizza': return Pizza(name); case 'Spaghetti': return Spaghetti(name); case 'RoastedChicken': return RoastedChicken(name); default: throw Exception('Invalid Dish type'); } } }
Test client program using the factory method implementation
void main() { Dish pizza = DishFactory.createDish('Pizza', 'Pepperoni'); Dish spaghetti = DishFactory.createDish('Spaghetti', 'Meatball'); Dish chicken = DishFactory.createDish('RoastedChicken', 'Roasted chicken'); pizza.cook(); spaghetti.cook(); chicken.cook(); }
Result
Cook Pepperoni Pizza
Cook Spaghetti
Cook Roasted Chicken
When to Use the Factory Method?
It’s best used when we don’t know the type of objects that will be created and it depends on other factors such as the user input and data from other classes in the app. For instance, in the above example, the type of dish to be created totally depends on the values passed from the main method which can be the user selection in the actual app. Different values leads to creating of different types of objects.
Why Do We Use Factory Method Design Pattern?
There are several advantages of using factory method in our software design:
- Increased Flexibility: factory method makes it easier to add new type of objects to an application without having any effect on existing code. For example, let’s say you have a shopping app that originally accepts cash and bank payment but later on you decide to add cryptocurrency payment. Doing this the usual way using the normal constructor may cause many errors in the existing code but using factory method, all you need to do is to simple add a new concrete class of the type cryptocurrency instead of having to modify lots of code. Hence our code is loosely coupled and more maintainable.
- Improved code readability: factory method encapsulates the object creation process in a separate factory class, making the code cleaner and more readable to the developer.
- Easier maintenance: changing the code implementation is way easier with this method without affecting the original code. As a result, it’s easier to fix bugs and errors, add new features, and improve the overall performance of the app.
However, the factory method has some disadvantages to consider:
- Complexity: The Factory Method pattern involves creating several classes and methods, which can add complexity to the code. This complexity can make the code more difficult to understand
- Increased number of classes: The Factory Method pattern requires the creation of several classes, including an abstract Creator class, concrete Creator subclasses, and an abstract Product class. This increase in the number of classes can make the code more difficult to understand
- Overhead: The Factory Method pattern adds an additional layer of abstraction to the code, which can increase the overhead of creating objects. This overhead may not be significant for small projects, but it can become a problem for large projects with many objects.
Despite these disadvantages, the Factory Method pattern is a powerful tool for creating objects in a centralized and consistent manner. It provides a level of abstraction that allows for flexibility and the ability to create objects of different types. The Factory Method pattern is particularly useful in situations where there is a need to create objects of different types, but the objects must be created in a consistent manner.
Conclusion
This brings an end to our tutorial where we went through factory method design pattern in-depth and full coverage. We’ve explored what factory pattern is, and learnt when it’s best to use it and how. We’ve dived into its advantages and disadvantages and went through a code example to see how to implement it effectively.
In today’s fast-paced development world, it’s essential to have the tool of design patterns knowledge in your toolkit. Whether you’re dealing with a small project or a massive enterprise application, these patterns are designed to handle problems you may encounter, and providing flexible and scalable ways to perform various functions. Whether you’re a seasoned developer or just starting out, the software design patterns are a valuable resource that will help you take your development skills to the next level. Don’t miss out on this opportunity to unlock the full potential of your code!
I hope this post was helpful and taught you something! Don’t forget to like and share my post with those interested in learning about design patterns.
Thank you for reading and Happy Coding!