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