2015-01-16 12 views
6

Tôi có một câu hỏi liên quan đến "Mẫu Builder" được đề cập trong "Java hiệu quả". Chúng ta có cần một phương thức .build() để nó có thể triển khai đúng mẫu không? Ví dụ, giả sử rằng chúng ta có lớp sau:Chúng ta có cần phương thức .build() trong Mẫu Builder không?

public class CoffeeDrink { 

    private int numEspressoShots; 
    private short milkType; 
    private boolean withWhip; 

    private CoffeeDrink() { 
    } 

    public static CoffeeDrink buildNewDrink() { 
     return new CoffeeDrink(); 
    } 

    public CoffeeDrink withEspresso(int n) { 
     this.numEspressoShots = n; 
     return this; 
    } 

    public CoffeeDrink withMilkType(shot t) { 
     this.milkType = t; 
     return this; 
    } 

    public CoffeeDrink withWhip() { 
     this.withWhip = true; 
     return this; 
    } 
} 

Và rồi thế nào chúng ta sử dụng nó:

CoffeeDrink c = CoffeeDrink.buildNewDrink() 
         .withEspresso(2) 
         .withMilkType(2) 
         .withWhip(); 

có này vẫn có giá trị nếu tôi không có một nội Builder lớp tĩnh? Tôi đoán rằng một trong những lợi thế là nó giữ tắt từ việc tạo ra một đối tượng CoffeeDrink mới cho đến khi phương thức .build() được gọi, nhưng tôi vẫn đang tạo đối tượng Builder. Chỉ cần tìm kiếm một số giải thích.

+1

Các mẫu Builder được sử dụng để lợi thế lớn với các lớp không thay đổi. Với họ, Builder là một lớp "trợ giúp" có thể thay đổi giúp hỗ trợ việc xây dựng cuối cùng của sản phẩm cuối cùng mà sau đó không thay đổi được. Ví dụ của bạn chỉ đơn thuần là một POJO đơn giản và nó chia sẻ những bất lợi của JavaBeans (có thể thay đổi, có thể được xem ở trạng thái không hoàn chỉnh hoặc không nhất quán, v.v.). – scottb

Trả lời

14

Không, đây không phải là mẫu Builder. Đó là Java hợp lệ, và nó sẽ biên dịch và chạy. Tuy nhiên, phương pháp buildNewDrink() của bạn, cho dù đó là phương thức build() hoặc buildNewDrink() hoặc một thứ khác, chỉ là một phương pháp nhà máy đơn giản tạo ra một CoffeeDrink. Những phương pháp khác giống như các phương thức setter xảy ra để tự quay trở lại.

Cần có static lớp Trình tạo lồng nhau. Trong khi giữ việc tạo cá thể lớp, nó có thể thực hiện logic xác thực để đảm bảo rằng một đối tượng không hợp lệ không được tạo ra. Tôi không chắc rằng có một trạng thái không hợp lệ đối với một số CoffeeDrink như bạn có, nhưng nếu nó đã làm, với mã của bạn, nó sẽ có thể tạo ra một CoffeeDrink và có nó ở trạng thái không hợp lệ sau khi nó được tạo ra, nhưng trước đó các phương pháp khác được gọi. Mẫu Builder loại bỏ khả năng này bằng cách xác nhận hợp lệ dữ liệu trước khi tạo cá thể. Nó cũng giúp loại bỏ sự cần thiết cho nổ xây dựng, nơi có rất nhiều nhà thầu với tất cả các kết hợp các thông số có thể cần thiết, để bao gồm tất cả các trường hợp có thể xảy ra.

+0

Tôi đồng ý với nhận xét của bạn. Những phương pháp này dường như là những người định cư thường xuyên với * chuỗi *. Chỉ là một chi tiết nhỏ, nhưng bạn có thể bị thiếu * "không" * trong câu trả lời của bạn, như trong * "nó có thể thực hiện logic xác nhận để đảm bảo rằng một đối tượng không hợp lệ là ** không ** tạo" *. – afsantos

+0

@afsantos Cảm ơn; sửa chữa. – rgettman

+0

Cảm ơn bạn đã làm rõ. Vì vậy, tôi sẽ xác nhận hợp lệ tất cả các tham số trong hàm xây dựng của lớp Builder, trước khi trả về cá thể của CoffeeDrink? – victormejia

1

Theo tham chiếu GoF, build() là không bắt buộc. Tham chiếu gốc không sử dụng chuỗi và có một bước getResult() ở cuối phương thức Director.construct(). Lớp Director đảm nhiệm việc đóng gói quá trình xây dựng, do đó, Client không cần phải lo lắng nếu chúng đang xây dựng mọi thứ một cách chính xác. Đó là trách nhiệm của Director.

Dưới đây là sơ đồ chuỗi từ tài liệu tham khảo GOF trên Builder:

GoF Builder Sequence Diagram

Các vấn đề liên quan