我正在学习Builder模式。我有一个问题,为什么不使用类(例如:MyCoffe)而不是2类(例如:MyCoffe,BuilderClass)。谢谢你的阅读。
package Creational.Builder;
public class MyCoffe {
private String name;
private int id;
public MyCoffe(){
}
public MyCoffe setName(String newName){
this.name = newName;
return this;
}
public MyCoffe setId(int newId){
this.id = newId;
return this;
}
public MyCoffe build(){
return this;
}
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe().setName("HelloWorld").setId(9999);
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}
答案 0 :(得分:4)
在某些选择的情况下,你肯定可以,但构建器模式的目的之一是避免使用类的无效实例。因此,除非MyCoffe
没有名称或ID,否则您不希望它的实例在没有名称或ID的情况下运行,如下所示:
MyCoffe invalid = new MyCoffe();
另请注意,当课程像这样自我构建时,很容易忘记调用最终build
方法(事实上,您在main
中执行了此操作) ,所以实例永远不会得到验证。
因此,在构建完整有效的实例之前,使用单独的构建器来保存不完整的信息。
在Java中,构建器作为静态嵌套类并不罕见:
public class MyCoffe {
public static class Builder {
private String name;
private int id;
public Builder() {
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setId(int id) {
this.id = id;
return this;
}
public MyCoffe build() {
if (this.name == null) {
throw new AppropriateException("'name' is required");
}
if (this.id == 0) { // Assumes 0 isn't a valid ID
throw new AppropriateException("'id' is required");
}
return new MyCoffe(name, id);
}
}
private String name;
private int id;
public MyCoffe(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe.Builder().setName("HelloWorld").setId(9999).build();
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}
或者,如果两次声明属性会让您感到困扰,MyCoffe
可以允许私有不完整的实例,如下所示:
public class MyCoffe {
public static class Builder {
private MyCoffe instance;
public Builder() {
this.instance = new MyCoffe();
}
public Builder setName(String name) {
this.instance.name = name;
return this;
}
public Builder setId(int id) {
this.instance.id = id;
return this;
}
public MyCoffe build() {
if (this.instance.name == null) {
throw new AppropriateException("'name' is required");
}
if (this.instance.id == 0) { // Assumes 0 isn't a valid ID
throw new AppropriateException("'id' is required");
}
return this.instance;
}
}
private String name;
private int id;
private MyCoffe() {
}
public MyCoffe(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe.Builder().setName("HelloWorld").setId(9999).build();
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}