设计模式之Builder模式
来源:互联网 发布:吉他教学视频软件 编辑:程序博客网 时间:2024/05/15 10:44
情景需要:
假设有这样一个Human类,要构造一个Human对象必须传递6个参数,其中前3个是必须的,后3个是可选的:
- class Human {
- // required parameters
- private final String name;
- private final String gender;
- private final int age;
- // optional parameters
- private final int height;
- private final int weight;
- private final String country;
- }
那么,给这个类设计构造方法会是比较头疼的事。
一种方案是,我们可以设计一个有6个参数的构造方法,分别给name, gender, height, weight, country赋值,其中后3个值可以有缺省值。如:
- public Human(String name, String gender, int age, int height = 180, int weight = 50, String country = "China") {
- //... ...
- }
然而这样设计有一个不足之处,那就是后3个参数虽然有缺省值,但参数的顺序是固定的,不能变的,如果用户在传参的时候把顺序搞错了,就会产生错误。而且如果参数类型相同的话,编译器也不会报错。为了弥补这样的不足,我们可以重载构造方法,如:
- public Human(String name, String gender, int age) {}
- public Human(int height) {} // 不能构成重载
- public Human(int weight) {} // 不能构造重载
- public Human(String country) {}
这样虽然解决了参数顺序的问题,但如果这个类的可选参数有不只3个,比如有6个,10个,20个的话,那么就要设计大量的重载的方法,非常费事。而且上面的代码还存在一个问题,那就是第2个和第3个方法根本无法构成重载。也就是说,当可选参数的参数类型有重复的时候,上面的设计方法就不可行了。
这时候我们就可以采用 Builder模式 来解决这样问题。
Builder模式
我们可以在Human的内部定义一个静态的内部类Builder,通过这个类来完成对参数的赋值工作,如:
class Human {// required parametersprivate final String name;private final String male;private final int age;// optional parametersprivate final int height;private final int weight;private final String country;// builder classpublic static class Builder {// required parametersprivate final String name;private final String male;private final int age;// optional parametersprivate int height = 0;private int weight = 0;private String country = "none";public Builder(String name, String male, int age) {this.name = name;this.male = male;this.age = age;}public Builder setHeight(int h) {this.height = h;return this;}public Builder setWeight(int w) {this.weight = w;return this;}public Builder setCountry(String c) {this.country = c;return this;}public Human build() {return new Human(this);}}}
然后为Human提供一个私有的构造方法,以Builder对象作为其形参,在此构造方法中完成参数的赋值:
- private Human(Builder b) {
- name = b.name;
- gender = b.gender;
- age = b.age;
- height = b.height;
- weight = b.weight;
- country = b.country;
- }
这样一来,用户 在使用Human 这个类的时候,就可能以如下的方式来构造Human对象:
- Human hm = new Human.Builder("bruce", "male", 20) // 设置必须参数
- .setCountry("China") // 设置可选参数
- .setWeight(50) // 设置可选参数
- .build(); // 构造对象
显然,Human类的使用者在创建其对象时所写的代码就变得简单明了多了。
因此,当一个类的构造方法必须传递大量参数的时候,我们可以考虑使用Builder模式来构造此类。当应用程序对性能要求不是很高时,Builder模式是处理此类情形的最好方案。
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之 builder
- 设计模式之Builder
- 设计模式之builder
- 键盘输入和字符集的故事
- 没什么
- C内存管理
- NSNumber,NSValue,NSDate的使用
- experiment : use class member function pointer
- 设计模式之Builder模式
- hibernate之Criteria限定返回的记录范围
- xenomai rt_sem 信号量
- C语言中可变参数函数的设计
- poj2368 Buttons
- Flex中常见的图
- BNU16490:Give Me the Number(模拟)
- 不要一个人吃饭
- Android的单线程模型