绍兴网站建设模板网站,重庆网站开发 公司,如何进入网页编辑,打不开wordpress站点目录 一、为什么需要建造者模式#xff1f;1、场景12、场景23、解决上述场景的办法#xff1a;建造者模式 二、练习1、题目描述 【[来源](https://kamacoder.com/problempage.php?pid1084)】2、输入描述3、输出描述4、输入示例5、输出示例6、参考 三、思考1、一般常用的是lo… 目录 一、为什么需要建造者模式1、场景12、场景23、解决上述场景的办法建造者模式 二、练习1、题目描述 【[来源](https://kamacoder.com/problempage.php?pid1084)】2、输入描述3、输出描述4、输入示例5、输出示例6、参考 三、思考1、一般常用的是lombok库的Builder注解。2、但Builder注解有很多坑点3、不如用Accessors(chain true) 一、为什么需要建造者模式 什么时候使用建造者模式 1、场景1
有时候一个类中有很多字段或者有些字段也是引用类型。这时候当我们实例化这个类时建造这个类的对象时会比较麻烦方案提供入参巨多的构造器
public class ComplexClass {private String name;private String email;private Integer age;private Pet pet;...public ComplexClass(String name, String email, ...) {}
}2、场景2
有各种各样的房子它们有一些共同的属性也有一些独特的属性。一种设计是抽象父类 多个子类。这可能导致子类爆炸明明也是房子对象却不得不搞一个新的房子类。
3、解决上述场景的办法建造者模式
示例
public class House { private ListWall walls;private ListDoor doors;...
}public interface IHouseBuilder {void buildWalls(ListWall walls);void buildDoors(ListDoor doors);...House getProduct();
}public class HouseWithGarageBuilder implements IHouseBuilder {private House house;public HouseWithGarageBuilder() {house new House();}public buildWalls(ListWall walls) {this.walls walls;}public buildDoors(ListDoor doors) {this.doors doors; }...public House getProduct() {return house;}
}public class HouseDirector {private IHouseBuilder builder;public HouseDirector(IHouseBuilder builder) {this.builder builder;}public House constructHouse() {builder.buildWalls(...);builder.buildDoors(...);return builder.getProduct();}
}本质分步骤建造对象。
二、练习
1、题目描述 【来源】 小明家新开了一家自行车工厂用于使用自行车配件车架 frame 和车轮 tires 进行组装定制不同的自行车包括山地车和公路车。 山地车使用的是Aluminum Frame铝制车架和 Knobby Tires可抓地轮胎公路车使用的是 Carbon Frame 碳车架和 Slim Tries。 现在它收到了一笔订单要求定制一批自行车请你使用【建造者模式】告诉小明这笔订单需要使用那些自行车配置吧。 2、输入描述 输入的第一行是一个整数 N1 ≤ N ≤ 100表示订单的数量。 接下来的 N 行每行输入一个字符串字符串表示客户的自行车需求。 字符串可以包含关键词 “mountain” 或 “road”表示客户需要山地自行车或公路自行车。 3、输出描述 对于每笔订单输出该订单定制的自行车配置。 4、输入示例 3 mountain road mountain 5、输出示例 Aluminum Frame Knobby Tires Carbon Frame Slim Tires Aluminum Frame Knobby Tires 6、参考
Data
NoArgsConstructor
AllArgsConstructor
public class Bike {private Frame frame;private Tires tires;Overridepublic String toString() {return frame.getType() tires.getType();}
}Data
NoArgsConstructor
AllArgsConstructor
public class Frame {private String type;
}Data
NoArgsConstructor
AllArgsConstructor
public class Tires {private String type;
}public interface IBikeBuilder {void buildFrame();void buildTires();Bike getProduct();
}public class MountainBikeBuilder implements IBikeBuilder {private Bike bike;public MountainBikeBuilder() {bike new Bike();}Overridepublic void buildFrame() {bike.setFrame(new Frame(Aluminum Frame));}Overridepublic void buildTires() {bike.setTires(new Tires(Knobby Tires));}Overridepublic Bike getProduct() {return bike;}
}public class RoadBikeBuilder implements IBikeBuilder {private Bike bike;public RoadBikeBuilder() {bike new Bike();}Overridepublic void buildFrame() {bike.setFrame(new Frame(Carbon Frame));}Overridepublic void buildTires() {bike.setTires(new Tires(Slim Tries));}Overridepublic Bike getProduct() {return bike;}
}public class BikeDirector {public Bike constructBike(IBikeBuilder bikeBuilder) {bikeBuilder.buildFrame();bikeBuilder.buildTires();return bikeBuilder.getProduct();}
}public class Main {public static void main(String[] args) {BikeDirector bikeDirector new BikeDirector();Scanner scanner new Scanner(System.in);int n scanner.nextInt();scanner.nextLine();for (int i 0; i n; i) {String type scanner.nextLine();IBikeBuilder bikeBuilder;if (mountain.equals(type)) {bikeBuilder new MountainBikeBuilder();} else if (road.equals(type)) {bikeBuilder new RoadBikeBuilder();} else {throw new RuntimeException(type error);}Bike bike bikeDirector.constructBike(bikeBuilder);System.out.println(bike.toString());}}
}三、思考
现实情况下我还没这么用过建造者模式因为按照上面的写法还是很费劲的。
1、一般常用的是lombok库的Builder注解。
示例
Builder
ToString
public class User {private String name;private Integer age;private String email;private String gender;
}public class Main {public static void main(String[] args) {User user User.builder().name(Forrest).age(20).email(forrestqq.com).gender(male).build();System.out.println(user);}
}这种建造对象的写法看起来还是很舒服的。 编译后的User.class
public class User {private String name;private Integer age;private String email;private String gender;User(String name, Integer age, String email, String gender) {this.name name;this.age age;this.email email;this.gender gender;}public static UserBuilder builder() {return new UserBuilder();}public String toString() {return User(name this.name , age this.age , email this.email , gender this.gender );}public static class UserBuilder {private String name;private Integer age;private String email;private String gender;UserBuilder() {}public UserBuilder name(String name) {this.name name;return this;}public UserBuilder age(Integer age) {this.age age;return this;}public UserBuilder email(String email) {this.email email;return this;}public UserBuilder gender(String gender) {this.gender gender;return this;}public User build() {return new User(this.name, this.age, this.email, this.gender);}public String toString() {return User.UserBuilder(name this.name , age this.age , email this.email , gender this.gender );}}
}可以清楚地看到User中生成了一个内部类UserBuilder来分步骤设置字段。
2、但Builder注解有很多坑点
显而易见的一点
Builder
ToString
public class User {private String name Forrest;private Integer age;private String email;private String gender;
}public class Main {public static void main(String[] args) {User user User.builder().age(20).email(forrestqq.com).gender(male).build();System.out.println(user);}
}User(namenull, age20, emailforrestqq.com, gendermale)默认值就这样丢了…
Builder
ToString
AllArgsConstructor
public class User {private String name Forrest;private Integer age;private String email;private String gender;public User(Integer age, String email, String gender) {this.age age;this.email email;this.gender gender;}
}public class Main {public static void main(String[] args) {User user new User(20, forrestqq.com, male);System.out.println(user);}
}User(nameForrest, age20, emailforrestqq.com, gendermale)不得不加上AllArgsConstructor因为Builder生成的UserBuilder中用到了全参构造器。
3、不如用Accessors(chain true)
Data
Accessors(chain true)
public class User {private String name Forrest;private Integer age;private String email;private String gender;
}public class Main {public static void main(String[] args) {User user new User().setAge(18).setEmail(forrestqq.com).setGender(male);System.out.println(user);}
}User(nameForrest, age18, emailforrestqq.com, gendermale)