Chapter 1 begins with a discussion of the creative design pattern, which focuses on creating classes to make code extensible.
Wechat official account Codog code:
1
Builder Pattern
purpose
Reduce the number of constructors and remove constructors with too many arguments, which can cause readability and ease of use.
The example code
If we want to build a girlfriend (love yourself, other people’s girlfriend is not the country to send yao, I how also need their new, the country in the end when to send me 😢)
Girlfriend has many attributes, such as age, gender, name, etc., we may know different attributes at different stages, so we design the girlfriend category as follows:
Initial implementation
@Getter@Setterpublic class GirlFriend {/** ** date of birth */ private LocalDateTime birthDay; /** * name */ private String name; /** * constellation */ private ConstellationEnum constellation; /** * hometown */ private String hometown; /** * height */ private Integer height; /** * weight */ private Integer weight; /** ** private CupEnum cup; @badsmell public GirlFriend(String name) {this.name = name; /** * @badsmell public GirlFriend(String name) {this.name = name; } /** * START dating chat, START checking household registration * START: where do you live ** G: Inner Mongolia * I: Prairie, riding a horse to school, archery exam * G: Fujian * I: selling tea * G: Beijing * I: You can't see people when you walk in that haze * G: Sichuan * I: Your spicy * G: Hefei * I:... * @param birthDay * @param name * @param constellation * @param hometown * @param height * @param weight */ @BadSmell public GirlFriend( LocalDateTime birthDay, String name, ConstellationEnum constellation, String hometown, Integer height, Integer weight) { this.birthDay = birthDay; this.name = name; this.constellation = constellation; this.hometown = hometown; this.height = height; this.weight = weight; } /** * start a deep chat... * Otherwise, how do you think the last entry knows * what? What touch, * @param birthDay * @param name * @param constellation * @param hometown * @param height * @param weight * @param cup */ @BadSmell public GirlFriend( LocalDateTime birthDay, String name, ConstellationEnum constellation, String hometown, Integer height, Integer weight, CupEnum cup) { this.birthDay = birthDay; this.name = name; this.constellation = constellation; this.hometown = hometown; this.height = height; this.weight = weight; this.cup = cup; }}Copy the code
Problem analysis
We think there are three problems
There are too many constructors
If we were an experienced driver and knew our girlfriend’s CUP at a glance, we might add another constructor like this:
/** * @param name * @param cup */ @badsmell public GirlFriend(String name, CupEnum cup) {this.name = name; this.cup = cup; }Copy the code
If we were introduced by a friend as a young girl, 18 years old (go to sleep, 18-year-old girls don’t like you… We know her age, we don’t even know her name, we have to add another constructor
/** * * @param birthDay */ @badsmell public GirlFriend(LocalDateTime birthDay) {this. BirthDay = birthDay; }Copy the code
Two. The third one has too many inputs
The height and weight are both Integer, one error will change a girl who is 168 cm and 50 kg into a girl who is 50 cm and 168 kg.
3. Poor scalability for new attributes
If we think of a new attribute today, we need to write it down, such as girlfriend occupation (student, white collar, clerk, programmer, teacher), such as blood type, etc.
If we want to construct all of them, we may need to add the 2^(n-1) constructor, which is hopeless 😳
Tentative solution
After reading the above analysis, we suddenly realized that since it is so complicated to construct a girlfriend using constructors, we should not construct one in our life
Since we are good programmers, solving this problem is much easier than finding a girlfriend in life (at least the constructor doesn’t hate our hair loss 😊).
Ok, so how do we solve this, since the number of constructors is expanding exponentially, how about instead of using constructors, how about using a no-parameter constructor and a Set method
/ * * * use a no-parameter constructor and Setter complete object assembling * / public static void buildGirlFriendWithSetter () {GirlFriend GirlFriend = new GirlFriend(); girlFriend.setBirthDay(LocalDateTime.now()); girlFriend.setName(""); girlFriend.setConstellation(null); girlFriend.setHometown(""); girlFriend.setHeight(0); girlFriend.setWeight(0); girlFriend.setCup(null); . }Copy the code
The drawback is obvious, the code is too long, set line after set line
Using Builder Mode
public final class GirlFriendBuilder { private LocalDateTime birthDay; private String name; private ConstellationEnum constellation; private String hometown; private Integer height; private Integer weight; private CupEnum cup; private GirlFriendBuilder() {}public static GirlFriendBuilder aGirlFriend() { return new GirlFriendBuilder(); } public GirlFriendBuilder withBirthDay(LocalDateTime birthDay) { this.birthDay = birthDay; return this; } public GirlFriendBuilder withName(String name) { this.name = name; return this; } public GirlFriendBuilder withConstellation(ConstellationEnum constellation) { this.constellation = constellation; return this; } public GirlFriendBuilder withHometown(String hometown) { this.hometown = hometown; return this; } public GirlFriendBuilder withHeight(Integer height) { this.height = height; return this; } public GirlFriendBuilder withWeight(Integer weight) { this.weight = weight; return this; } public GirlFriendBuilder withCup(CupEnum cup) { this.cup = cup; return this; } public GirlFriend build() { GirlFriend girlFriend = new GirlFriend(); girlFriend.setBirthDay(birthDay); girlFriend.setName(name); girlFriend.setConstellation(constellation); girlFriend.setHometown(hometown); girlFriend.setHeight(height); girlFriend.setWeight(weight); girlFriend.setCup(cup); return girlFriend; }}Copy the code
Use the code above to build a custom girlfriend
GirlFriend cuiHuaGirlFriend = GirlFriendBuilder. AGirlFriend (.) withName (" cui flower "). WithHeight (168). WithWeight (50). The build ();Copy the code
Some of the problems mentioned above have been solved 😜
The final class diagram looks like this:
The production practice
Plug-ins can be used to help with repetitive development. For IDEA plug-in installation, see Part 2 of this article
Using the Builder plugin
Plug-in address: plugins.jetbrains.com/plugin/6585…
code -> generate
Just choose Builder
Use the Lombok plug-in
Plug-in address: plugins.jetbrains.com/plugin/6317…
Mavn introduces lombok dependencies
< the dependency > < groupId > org. Projectlombok < / groupId > < artifactId > lombok < / artifactId > < version > 1.18.8 < / version > </dependency>Copy the code
Label the classes you want to use
@builderPublic class GirlFriend {/** ** date of birth */ private LocalDateTime birthDay; . }Copy the code
Usage:
GirlFriend girlFriend = GirlFriend.builder().birthDay(LocalDateTime.now()).build();
Copy the code
Using Setter plug-ins
Plug-in address: plugins.jetbrains.com/plugin/9360…
2
IDEA How to install a plug-in
1. Find the Preferences -> Plugins
2. Enter the plug-in name XXX fuzzy search
3. Click Install and restart IDEA
3
Creator homework
1. Install and use the Setter, Builder, and Lombok plug-ins
2. Write silently to draw the general class diagram of Builder mode
3. Define a BoyFriend class and write and use the Builder pattern
4. As a bank developer, one day the product proposed to build a loan system, requiring you to design a loan product category, which includes the attribute term (20 days, 6 months, 2 years), repayment method (equal to the principal, interest before principal), and loan limit (200,000 RMB, 5,000 USD). Daily interest rate (0.5%), coupon list, list of supported receiving accounts, whether prepayment is supported, prepayment fee, whether the amount can be increased, use the full Builder model to construct products