Stripping cocoons and elaborating on the structure of those things - [Sharp Lessons]
Simple programs don't require a lot of design because they focus only on limited solutions and use only a few classes.Large programs focus on a wide range of designs that make more use of reusability than any other property of a good design paradigm.Ambitious ideas are not only solutions to current problems, but also the creation of a design that lays the foundation for future changes.Complex programs require thousands of lines of code and a lot of interaction between objects and users.These types of solutions are typically found in air traffic control systems and banking systems that operate with thousands of counters.This paper is the learning insights written after learning Excellent Design Modes in Learning Sources in JAVA Architecture VIP course - [Frame Source Theme].Here, we explore a design pattern called the builder pattern and implement it using Java code samples.
Deep Exploration of Java Design Patterns (1) Single Case Patterns
Explore Java Design Patterns (2) Strategic Patterns
Deep Exploration of Java Design Patterns (3) Decorator Patterns
Deep Exploration of Java Design Patterns (4) The Enjoyment Patterns
Overview
Effective software design not only meets current requirements, but also forms the basis for future changes and development.It's easier said than done in practice.However, design patterns undoubtedly reduce the burden of code design to a large extent.Patterns are mature architectures for building flexible and maintainable software.It greatly reduces code complexity through a set of standard specifications and practices.
There are many design patterns available, and developers can choose one based on the best representation of the code flow.It is almost impossible to choose a product that does not meet your needs.In fact, design patterns are proof that someone has encountered problems and designed best practices to get a solution.But they are by no means providence.A better idea is to replace them at any time.Rebels in a peaceful environment are suicidal.Although people can get out of their difficulties and do their own things, it is helpful to follow a design pattern in most cases.
Builder Mode
Design patterns are named according to their characteristics.For example, the builder pattern lists the specifications for building class structures.This is particularly useful when instantiating classes in object-oriented programming.The idea is to separate the construction of complex objects from their representations.It uses flexibility to design objects like Java.When we start coding, it's easy to feel the convenience of this design pattern.
Using builder mode
This pattern is particularly useful for creating instances of classes with many fields or attributes.Obviously, constructors are cumbersome in this case.For example, in such a category:
1 public class Person { 2 3 private final long id; 4 private final String firstName; 5 private final String middleName; //optional 6 private final String lastName; //optional 7 private final Date birthDate; 8 private final String phone; 9 private final String email; 10 11 private final String street; //optional 12 private final String city; //optional 13 private final String province; 14 private final String zip; 15 // ...
To create an instance of this type, we can:
- Initialize fields with values using a single constructor
- Using multiple constructors
- After instantiating an object with a parameterless constructor, use the setter method
Although these are syntactically valid techniques, they can be cumbersome in practice.As the number of fields increases, it will soon become difficult to manage and understand.Using a single constructor is a bad idea, first because initializing many fields with a large parameterized constructor is a bad design.Second, there are some choices to eliminate optional fields.Using multiple constructors is not a good idea, because if you increase the number of fields in the future, it will quickly become unmanageable.
The third method is to remove the final modifier from the field and initialize it using the setter method without using any constructors at all.The problem with this technique is that we can use the setter method to create such invalid objects.For example, the following is a semantically invalid instance of this class, although syntactically valid.
1 Person person = new Person(); 2 person.setCity("Mumbai");
Note that people's definition of objects is not only an effective initialization of city fields, but at least a proper initialization of non-optional fields.This is the real problem with setter method initialization.
Implement builder mode
We can use the builder pattern to overcome all the issues discussed above.Here, using this technique, we create an accompanying object called a generator.This companion object is used to construct a legal domain object.This not only improves the clarity of the code, but also simplifies the construction.
1 public class Person { 2 public static class Builder { 3 private long id; 4 private String firstName; 5 private String middleName; //optional 6 private String lastName; //optional 7 private Date birthDate; 8 private String phone; 9 private String email; 10 private String street; //optional 11 private String city; //optional 12 private String province; 13 private String zip; 14 public Builder id(final long id) { 15 this.id = id; 16 return this; 17 } 18 public Builder firstName(final String firstName) { 19 this.firstName = firstName; 20 return this; 21 } 22 public Builder middleName(final String middleName) { 23 this.middleName = middleName; 24 return this; 25 } 26 public Builder lastName(final String lastName) { 27 this.lastName = lastName; 28 return this; 29 } 30 public Builder birthDate(final Date birthDate) { 31 this.birthDate = birthDate; 32 return this; 33 } 34 public Builder phone(final String phone) { 35 this.phone = phone; 36 return this; 37 } 38 public Builder email(final String email) { 39 this.email = email; 40 return this; 41 } 42 public Builder street(final String street) { 43 this.street = street; 44 return this; 45 } 46 public Builder city(final String city) { 47 this.city = city; 48 return this; 49 } 50 public Builder province(final String province) { 51 this.province = province; 52 return this; 53 } 54 public Builder zip(final String zip) { 55 this.zip = zip; 56 return this; 57 } 58 public Person build(){ 59 if(id <= 0 || firstName.isEmpty() || 60 birthDate == null || phone.isEmpty() || 61 email.isEmpty() || province.isEmpty() || 62 zip.isEmpty()){ 63 throw new IllegalStateException("Cannot create 64 Person object."); 65 } 66 return new Person(id,firstName,middleName,lastName, 67 birthDate,phone,email,street,city,province,zip); 68 } 69 } 70 private final long id; 71 private final String firstName; 72 private final String middleName; //optional 73 private final String lastName; //optional 74 private final Date birthDate; 75 private final String phone; 76 private final String email; 77 private final String street; //optional 78 private final String city; //optional 79 private final String province; 80 private final String zip; 81 private Person(final long id, final String firstName, 82 final String middleName, final String lastName, 83 final Date birthDate, final String phone, 84 final String email, final String street, 85 final String city, final String province, 86 final String zip) { 87 this.id = id; 88 this.firstName = firstName; 89 this.middleName = middleName; 90 this.lastName = lastName; 91 this.birthDate = birthDate; 92 this.phone = phone; 93 this.email = email; 94 this.street = street; 95 this.city = city; 96 this.province = province; 97 this.zip = zip; 98 } 99 }
The Builder class is part of the Person class and is used to construct Person objects.For constructors, the parameters are sorted in a specific way.As a result, they are passed in the same order.When using the builder mode, order does not matter, and values can be passed in any order during construction.Note that in this case, the constructor is set to private.
1 @Test 2 public void rightBuild() { 3 final Person.Builder builder = new Person.Builder(); 4 final Person emp = builder 5 .id(101) 6 .firstName("Percy") 7 .middleName("Bysshe") 8 .lastName("Shelley") 9 .birthDate(new GregorianCalendar(1792, 10 Calendar.AUGUST,4).getTime()) 11 .phone("1234567890") 12 .email("pbs@gmail.com") 13 .street("123 somewhere") 14 .province("someplace") 15 .zip("10293847").build(); 16 } 17 @Test(expected = IllegalStateException.class) 18 public void wrongBuild() { 19 final Person.Builder builder = new Person.Builder(); 20 final Person emp = builder 21 .middleName("Bysshe") 22 .lastName("Shelley") 23 .phone("1234567890") 24 .zip("10293847").build(); 25 }
In the test method, observe how we create objects by calling the builder method and a series of method calls.Finally, call the build() method to end the chain and finish creating the object.This is how we implement the builder pattern in Java code.
conclusion
The essence is to understand the principles behind the builder pattern and implement it in your own way.However, in almost all cases, the pattern remains the same.As specified, the builder pattern is particularly useful in situations where a large number of fields in a class must be initialized.This pattern is not appropriate for each class.You can see that for convenience, lines of code have been added.Use it wisely and carefully.
Thanks for reading!Welcome to the message.Trust me if you want to delve deeper into learning.