DEV Community

loading...
Cover image for Master Design Patterns By Building Real Projects - Abstract Factory Pattern - Javascript

Master Design Patterns By Building Real Projects - Abstract Factory Pattern - Javascript

hieptl profile image Hiep Le Updated on ・4 min read

Creational Pattern - Abstract Factory Pattern.

This is the fifth part in my series (23 GoF Design Patterns). My series will help you understand about design patterns by building real projects. For this reason, you can see the places in which each pattern could be applied. I want to focus on learning by doing instead of talking too much about theories.

I'm Hiep. I work as a full-time software engineer. Most of my open-source projects are focused on one thing - to help people learn 📚.

I created a git repository that help you understand about design patterns by building real projects.

Github link:

https://github.com/hieptl/javascript-dessign-patterns

If the repository is useful, please help me share the post and give me a Github's star. It will make me feel motivation to work even harder. I will try to make many open sources and share to the community ❤️.

I also created some series that help you improve your practical skills ❤️

1. Learn React By Buiding Netflix

https://dev.to/hieptl/learn-react-by-building-netflix-1127

Table of Contents

1. Definition.

Abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. In other words, it is a factory of factories.

If you do not know about the factory pattern, You can refer to the following post:
https://dev.to/hieptl/master-design-patterns-by-building-real-projects-factory-pattern-javascript-13cb

2. Scenarios.

We can imagine that we want to build a website for a car showroom. The car showroom contains different types of cars. The car showroom decides to create a feature that help the end users find the cars easier. The feature let the end users input the car's type and the car's name which is belonging to that type.

The system should return the car's information based on input type and name.

Example: David visits our website, He inputs 'Mercedes' for the car's type and 'Maybach' for the car's name. Our website should return the information of 'Maybach' to him if it is existing in the car showroom.

We will bulid the feature by using Abstract Factory pattern.

3. Building a Car Showroom.

I want to use Javascript class to implement the idea because in the case you are using object-oriented programming languages or you have to use those languages in the future, you can still implement design patterns by using different languages. In my opinion, design patterns are mindset and approaches and not depend on programming languages.

Step 1: Create Car class to store the information of a car.

class Car {
  constructor(name, price, description) {
    this.name = name;
    this.price = price;
    this.description = description;
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create MercedesFactory class to return a car which is beloing to Mercedes based on input name.

class MercedesFactory {
  create(name) {
    switch(name) {
      case 'C300':
        return new Car(name, 2000, 'This is C300');
      case 'Maybach':
        return new Car(name, 5000, 'This is Maybach');
      default:
        return null;  
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create BMWFactory class to return a car which is beloing to BMW based on input name.

class BMWFactory {
  create(name) {
    switch(name) {
      case 'X5':
        return new Car(name, 1000, 'This is X5');
      case 'X6':
        return new Car(name, 2000, 'This is X6');
      default:
        return null;  
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Create CarAbstractFactory class to return a factory class based on input type.

class CarAbstractFactory {
  static getFactory(type) {
    switch(type) {
      case 'Mercedes':
        return new MercedesFactory();
      case 'BMW':
        return new BMWFactory();
      default:
        return null;    
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

We defined getFactory method as static because static method can be accessed directly by using the class's name.

Example: We can write

CarAbstractFactory.getFactory('Mercedes');

Instead of

const carAbstractFactory = new CarAbstractFactory();
carAbstractFactory.getFactory('MaybaMercedesch');

Our full source code will look like this:

class Car {
  constructor(name, price, description) {
    this.name = name;
    this.price = price;
    this.description = description;
  }
}

class MercedesFactory {
  create(name) {
    switch(name) {
      case 'C300':
        return new Car(name, 2000, 'This is C300');
      case 'Maybach':
        return new Car(name, 5000, 'This is Maybach');
      default:
        return null;  
    }
  }
}

class BMWFactory {
  create(name) {
    switch(name) {
      case 'X5':
        return new Car(name, 1000, 'This is X5');
      case 'X6':
        return new Car(name, 2000, 'This is X6');
      default:
        return null;  
    }
  }
}

class CarAbstractFactory {
  static getFactory(type) {
    switch(type) {
      case 'Mercedes':
        return new MercedesFactory();
      case 'BMW':
        return new BMWFactory();
      default:
        return null;    
    }
  }
}

const mercedesFactory = CarAbstractFactory.getFactory('Mercedes');

const car = mercedesFactory.create('Maybach');
console.log(car);
Enter fullscreen mode Exit fullscreen mode

4. Result.

Car { name: 'Maybach', price: 5000, description: 'This is Maybach' }
Enter fullscreen mode Exit fullscreen mode

The above result describes that our CarAbstractFactory return the factory based on input type and we can get the car by using that factory and input name.

By using design patterns, we can understand the core concepts and make our code become more readable and cleaner. I hope that the post can help you understand about Abstract Factory pattern.

Thanks and Best Regards,
Hiep.

Discussion (3)

Collapse
chatducheshire profile image
chat-du-cheshire

Hi, nice article!

Why Mercedes/BMW factory classes doesn't use static create?

Collapse
hieptl profile image
Hiep Le Author • Edited

Hi @chatducheshire ,

First of all, Thank you so much for your questions ❤️ Actually, I am waiting for that question 😄. When I were writing about this topic, I thought that someone would ask me that question 😄 Here is my explaination:

Static methods could be accessed directly by using the class's name, static methods belong to the class area not the object.

However, the CarAbstractFactory class returns a factory object by the given name. For this reason, if we define create methods as static. It means that we can access to them by writing something like this:

const firstCar = MercedesFactory.create('Maybach');
const secondCar = BMWFactory.create('X5');
Enter fullscreen mode Exit fullscreen mode

Therefore, returning the factory object from the CarAbstractFactory will not be meaningful. We should use the returned object from the abstract factory class. It will make sense. On the other hand, using static methods depends on your decision. I do not want to define create methods as static because I want the developers to have a clear meaning about the role of CarAbstractFactory.

I hope that my explaination could help you understand about why we did not define create methods as static.

Thanks and Best Regards,
Hiep

Collapse
chatducheshire profile image
chat-du-cheshire

Ok, thank you. Definitely I see no difference between static and prototype methods in this case. I think it about uniformity

Forem Open with the Forem app