Quay trở lại năm 2007, tôi đã đọc một bài viết về Joshua Blochs về "mẫu xây dựng" và cách nó có thể được sửa đổi để cải thiện việc sử dụng quá mức các hàm tạo và setters, đặc biệt là khi một đối tượng có số lượng lớn các thuộc tính, hầu hết là tùy chọn. Một bản tóm tắt ngắn gọn về mẫu thiết kế này được phát biểu ở đây .
Tôi thích ý tưởng này, và đã sử dụng nó từ đó. Vấn đề với nó, trong khi nó rất sạch sẽ và tốt đẹp để sử dụng từ góc độ khách hàng, thực hiện nó có thể là một nỗi đau trong ăn mày! Có rất nhiều vị trí khác nhau trong đối tượng trong đó một thuộc tính là tham chiếu và do đó tạo đối tượng và thêm một thuộc tính mới mất rất nhiều thời gian.
Vì vậy, ... tôi đã có một ý tưởng. Đầu tiên, một đối tượng ví dụ theo phong cách của Joshua Bloch:
Phong cách Josh Bloch:
public class OptionsJoshBlochStyle {
private final String option1;
private final int option2;
// ...other options here <<<<
public String getOption1() {
return option1;
}
public int getOption2() {
return option2;
}
public static class Builder {
private String option1;
private int option2;
// other options here <<<<<
public Builder option1(String option1) {
this.option1 = option1;
return this;
}
public Builder option2(int option2) {
this.option2 = option2;
return this;
}
public OptionsJoshBlochStyle build() {
return new OptionsJoshBlochStyle(this);
}
}
private OptionsJoshBlochStyle(Builder builder) {
this.option1 = builder.option1;
this.option2 = builder.option2;
// other options here <<<<<<
}
public static void main(String[] args) {
OptionsJoshBlochStyle optionsVariation1 = new OptionsJoshBlochStyle.Builder().option1("firefox").option2(1).build();
OptionsJoshBlochStyle optionsVariation2 = new OptionsJoshBlochStyle.Builder().option1("chrome").option2(2).build();
}
}
Bây giờ phiên bản "cải tiến" của tôi:
public class Options {
// note that these are not final
private String option1;
private int option2;
// ...other options here
public String getOption1() {
return option1;
}
public int getOption2() {
return option2;
}
public static class Builder {
private final Options options = new Options();
public Builder option1(String option1) {
this.options.option1 = option1;
return this;
}
public Builder option2(int option2) {
this.options.option2 = option2;
return this;
}
public Options build() {
return options;
}
}
private Options() {
}
public static void main(String[] args) {
Options optionsVariation1 = new Options.Builder().option1("firefox").option2(1).build();
Options optionsVariation2 = new Options.Builder().option1("chrome").option2(2).build();
}
}
Như bạn có thể thấy trong "phiên bản cải tiến" của tôi, có 2 vị trí ít hơn trong đó chúng tôi cần thêm mã về bất kỳ thuộc tính bổ sung nào (hoặc tùy chọn, trong trường hợp này)! Điểm trừ duy nhất mà tôi có thể thấy là các biến thể hiện của lớp bên ngoài không thể là cuối cùng. Nhưng, lớp học vẫn bất biến nếu không có điều này.
Có thực sự có bất kỳ nhược điểm để cải thiện khả năng bảo trì này? Có phải có một lý do mà anh ta lặp lại các thuộc tính trong lớp lồng mà tôi không thấy?