Choosing a good appropriate pattern would help make the code cleaner, easy to reuse, and limit the potential error, thereby speeding up the process of building.
Creational patterns aim to the creation of an object. There are five common patterns such as
1. Singleton
- This pattern ensures that only one instance of the class can be created at any time and it can access the value anywhere.
- The Singleton class contains
- A private class variable
- A private methodSingleton()
that is used to create the only instance.
- A public methodGetInstance()
returns the only instance. - By default, the singleton is not threadsafe. If we run many threads, it may cause the race condition and there is more than one instance object that could be created in the class. In order to prevent it, we need to use a synchronized block. The synchronized block ensures that only one thread can run on the block of code at the same time.
2. Factory Method
- We use this pattern when there is an extendable list of sub-class in the future and we want to wrap the generation into a common interface. It would help us not to change the code when there is a new sub-class.
- For example, we integrate API with many banks, and the number of banks may increase.
- In this pattern, there would be three elements such as
- super-class (base,interface,abstract module/class)
- sub-class
- factory-class (normal class, singleton class, or just public-static-method) - A factory initializes with an input variable and returns one of the sub-classes.
- super-class can be an interface, an abstract, or a base class.
3. Abstract Factory
- This pattern is about polymorphism Factories and they need an AbstractFactory to inherit
- Take a sample with the image above: A furniture company specializes in the production of chairs (Chair): plastic chairs (PlasticChair) and wooden chairs (WoodChair). With the business situation increasingly favorable, the company decided to expand the production of tables (Table). With the advantage of having experience in manufacturing chairs, the company still keeps the materials of plastic (PlasticTable) and wood (WoodTable) for table production. However, the manufacturing process of chairs/tables according to each material (MaterialType) is different. So the company splits up as a factory (Factory): one for the production of plastic materials (PlasticFactory), one for the production of wooden materials (WoodFactory), but both can produce chairs and tables (FunitureAbstractFactory). When a customer needs to buy an item, the customer (Client) only needs to go to the store to buy it (FunitureFactory). Then, for each good and material, it will be transferred to the respective workshop for production (createXXX) for tables (Table) and chairs (Chair).
4. Builder
This pattern aims to solve the disadvantage of the Factory Method Pattern and the Abstract Factory Pattern when an object has too many properties.
For example, we want to build a house but there are several house types and each type has many specific attributes that go along with it. It would be a bit messy if every time creating a new instance, we have to set all the properties manually. In order to reduce this cost, we can create a BuilderClass for generating some fixed object attributes.
5. Prototype
- This pattern is about cloning an instance from the inside instead cloning it from the outside.
- Here is an example, we implement the clone() for two objects Rectangle and Circle