Builder - Harsh4999/Design-Patterns GitHub Wiki
Creational design pattern.
Use cases
- Whenever we need to complete a class through multiple parts which are a different class itself we use builder design patterns.
- We have a complex process to construct an object involving multiple steps
- Remove logic related to object construction from client code & abstract it in seperate classes.
UML (Parts of the builder design)
- Final class: Result class which is composed of different parts(classes)
- Builder: It will provide you with interface to create parts of the final class.
- Concrete Builder: It is the implementation of the builder interface or abstract class. It is the main logic to create parts or final class. It will also assemble the final object. It can also keep track of the final object.
- Director: Uses builder to construct object. It knows how to use builder object in order to get final object.
Implementation
-
Identify the parts of the final class & provide methods to create the parts
-
Provide a method that assembles the parts to create the final object
-
Provice a way to get fully built object out through builder class also builder can keep reference of the object it created for future purposes.
-
Director can be seperate class or client can play the role of director.
-
Builder director should be closely built seeing the final class and implement utmost req vars.
-
Eg: We have an entity class user construct a builder with the director
Chain in which we get our user web dto. (User)-->[UserDTO]-->(UserWebDTO)
- In general we have the entity class (User)
- To create DTO of entity we first create the abstraction of the entity class so in future we can create many types of DTO [UserDTO]
- Final target DTO which will be made by builder (UserWebDTO)
How the user is converted to DTO with help of builders. [UserDTOBuilder]-->(UserWebDTOBuilder)
- Now the point to note here is that we built first the abstraction of the builder class as there can be many types of builder for dto class [UserDTOBuilder]
- We write the logic to input single user properties inside the builder and return the instance of builder to enable method chaining (UserWebDTOBuilder)
- Closely follow the target DTO to build the logic (UserWebDTOBuilder)
- We have the final build method which assembles everything to a target DTO class in the builder (UserWebDTOBuilder)
- We also keep the reference of the target class which we are building in the builder class (UserWebDTOBuilder)
How Director uses builder and user class to get DTO. (User)-->(BuilderDTO)-->(UserWebDTO)
- First director constructs or gets the User from the persistence layer (DB)
- The user is passed to the appropriate builder to convert it into DTO (Service)
- Builder releases the DTO which is later sent as response (Resource)
-
If we want to keep the target class immutable then we generally implement the builder class inside the DTO (Target class) itself i.e: (User)-->(UserWebDTO (UserWebDTOBuilder)) So further on whenever we want to make DTO out of base we just make new object of DTO class and pass on Builder the user it returns the DTO
-
Whenever we our into too much consideration of constructor we should always go for builder
-
Eg:
- String builder (Its not 100% builder pattern as builder should always allow us to build target with same steps everytime)
- Calendar builder
-
Example code here
Pitfalls
- Method chaining may be confusing
- Possiblity of partially initialized object