2012-07-12 34 views
10

Trong câu hỏi What is an efficient way to implement a singleton pattern in Java? câu trả lời với nhiều người trả lời nhất nói, để sử dụng một Enum để thực hiện một singleton.Đối phó với các Singletons phải phân lớp

Điều đó là tốt và tôi hiểu các đối số, tương ứng với lợi thế ngôn ngữ.

Tôi có, tuy nhiên, một tập hợp các lớp mà tôi định nghĩa singleton nhưng cần phải mở rộng các lớp khác, điều này là không thể với phương pháp enum, vì enums không thể phân lớp.

Joshua Bloch nói trong slide của mình:

  • Nhưng có một điều là mất tích-bạn không thể mở rộng một kiểu enum
    • Trong hầu hết các trường hợp, bạn không nên
    • Một trường hợp sử dụng hấp dẫn — mã hoạt động

Trong hầu hết các trường hợp, bạn không nên: ai đó có thể xây dựng trên đó? Tôi đã thực hiện một số servlets và họ mở rộng HttpServlet, tại sao không nên là những người độc thân? Tôi chỉ muốn một ví dụ của họ trong đơn của tôi.

+0

Bạn có thể giải thích tại sao bạn muốn một servlet đơn (các ràng buộc dẫn đến lựa chọn này) là gì? – Romski

+0

@Romski Ứng dụng này chỉ cần một cá thể của servlet này. – Mahoni

+0

enum có thể thực hiện các giao diện. Với việc ủy ​​quyền này có nghĩa là bạn chỉ có một cá thể sử dụng chức năng được định nghĩa trong một lớp khác. –

Trả lời

7

Lớp Singleton có thể mở rộng các lớp khác; thực sự theo mặc định trong Java nó sẽ mở rộng đối tượng. Tuy nhiên những gì Josh được đề cập đến là bạn không nên mở rộng một lớp Singleton bởi vì một khi bạn mở rộng nó, có hơn 1 trường hợp hiện tại.

trả lời bình luận:

Thực ra cách tốt nhất để thực hiện Singleton là:

Từ Effective Java

// Singleton with static factory 
public class Elvis { 
private static final Elvis INSTANCE = new Elvis(); 
private Elvis() { ... } 
public static Elvis getInstance() { return INSTANCE; } 
public void leaveTheBuilding() { ... } 
} 

Đây Elvis có thể mở rộng bất kỳ lớp khác.

+0

Và làm thế nào điều đó giúp tôi trong việc thực hiện servlet của tôi với thành ngữ enum? Lớp Singleton được triển khai bằng kiểu enum, ** không thể ** mở rộng các lớp khác. – Mahoni

+0

Không, một phần trực tuyến của "Java hiệu quả" cho biết cách tiếp cận enum. >> Cách tiếp cận này có chức năng tương đương với cách tiếp cận trường công cộng, ngoại trừ việc nó ngắn gọn hơn, cung cấp máy móc tuần tự miễn phí, và cung cấp bảo đảm chắc chắn chống lại nhiều instantiation, ngay cả khi đối mặt với các cuộc tấn công serialization hoặc phản chiếu phức tạp. Trong khi cách tiếp cận này vẫn chưa được áp dụng rộng rãi, một kiểu enum đơn nguyên tố ** là cách tốt nhất để thực hiện một singleton ** << – Mahoni

+2

Có lẽ tôi nên nói, một trong những cách tốt hơn. Nhưng đối với bạn, đây sẽ là cách tốt nhất vì bạn muốn mở rộng. – user1168577

1

Josh đang đề cập đến việc mở rộng loại enum, không phải để có loại singleton mở rộng cái gì khác.

+0

Nhưng tôi không thể thực hiện servlet của tôi với thành ngữ enum singleton, vì cách này nó không thể phân lớp 'HttpServlet':' public enum MyServlet mở rộng HttpServlet' là không được phép. Tôi không muốn mở rộng singleton của mình, tôi muốn để singleton của tôi mở rộng một lớp khác. – Mahoni

+0

Có, rõ ràng. Những gì tôi đang nói là Josh đã không giải quyết vấn đề đó trong báo giá này;) Rõ ràng là bạn không thể sử dụng thành ngữ enum trong trường hợp này, vậy vấn đề là gì? –

3

Bạn không nên quan tâm đến (các) thực thể của servlet của bạn - quản lý vòng đời được xử lý bởi thùng chứa servlet theo hợp đồng đặc tả Servlet mà bạn đã đồng ý. Nếu nó có ý nghĩa để thực hiện các phần của bạn chức năng phía máy chủ như một singleton, sau đó đi trước và làm điều đó bất kỳ cách nào bạn thích và sử dụng nó từ servlet của bạn.

+0

Điều đó có ý nghĩa! – Mahoni

+0

Câu hỏi này giải quyết được vấn đề của tôi, nhưng vì câu hỏi của tôi là tổng quát hơn, tôi đã quyết định kiểm tra câu hỏi khác như đã được loại trừ. Dù sao cũng cảm ơn bạn! – Mahoni

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