Đầu tiên, bạn bè cho bạn lựa chọn trong ánh sáng Java: Sách của Bloch là một lớp lót tuyệt vời.
Để trả lời câu hỏi thứ 2 của bạn ('không giống như phương thức khởi tạo của nhà máy tĩnh không bắt buộc phải tạo đối tượng mới mỗi lần được gọi'), điều quan trọng là nhận ra rằng những gì Bloch đang nói ở đây là với một nhà máy tĩnh bạn có tùy chọn của một trong hai: trả về một đối tượng mới hoặc trả về một đối tượng đã tồn tại từ trước. Tất cả phụ thuộc vào những gì bạn muốn làm.
Ví dụ: giả sử bạn có loại giá trị thực sự đơn giản của loại Tiền. Phương pháp nhà máy tĩnh của bạn có thể sẽ trả về một cá thể mới - tức là một đối tượng mới có giá trị cụ thể cho Tiền. Vì vậy, như sau:
public class Money {
private Money(String amount) { ... } /* Note the 'private'-constructor */
public static Money newInstance(String amount) {
return new Money(amount);
}
}
Nhưng giả sử bạn có một số đối tượng quản lý tài nguyên và bạn muốn đồng bộ hóa quyền truy cập vào tài nguyên đó thông qua một số lớp ResourceManager. Trong trường hợp đó, bạn có thể muốn phương thức factory tĩnh của bạn trả về cùng một cá thể của chính nó cho tất cả mọi người - buộc mọi người phải trải qua cùng một cá thể đó, sao cho 1 instance đó có thể kiểm soát quá trình. Điều này tuân theo mẫu đơn. Một cái gì đó như thế này:
public ResourceManager {
private final static ResourceManager me = new ResourceManager();
private ResourceManager() { ... } /* Note the 'private'-constructor */
public static ResourceManager getSingleton() {
return ResourceManager.me;
}
}
Phương pháp trên buộc người dùng của bạn chỉ có thể kiểm soát chính xác ai (và khi nào) có quyền truy cập vào bất kỳ thứ gì bạn đang quản lý.
Để trả lời câu hỏi đầu tiên của bạn, hãy xem xét này (phải thừa nhận là không phải là ví dụ tốt nhất, nó khá ad-hoc):
public class Money {
private Money(String amount) { ... }
public static Money getLocalizedMoney(MoneyType localizedMoneyType, String amount) {
switch(localizedMoneyType) {
case MoneyType.US:
return new Money_US(amount);
case MoneyType.BR:
return new Money_BR(amount);
default:
return new Money_US(amount);
}
}
}
public class Money_US extends Money { ... }
public class Money_BR extends Money { ... }
Lưu ý làm thế nào tôi bây giờ có thể làm điều này:
Money money = Money.getLocalizedMoney(user_selected_money_type);
saveLocalizedMoney(money);
Một lần nữa, một ví dụ thực sự giả tạo nhưng hy vọng nó sẽ giúp bạn nhìn thấy nhiều hơn hoặc ít hơn những gì Bloch đã nhận được tại thời điểm đó.
Các câu trả lời khác là tốt - tôi chỉ nghĩ rằng, là người mới bắt đầu, đôi khi nó giúp thấy một số mã thực tế.
+1 để tìm hiểu sâu về thực hành thiết kế phần mềm và đặt câu hỏi hay. –
Cảm ơn Brian :) – t0mcat
+1 vì đã hỏi TẠI SAO thay vì chỉ lập trình bằng cách viết. Thói quen của một coder tốt. – TreyE