2011-12-02 26 views
6

Tôi đang sử dụng trình điều khiển java cho MongoDB, và các tài liệu nói đến: "bạn nên tạo một trường hợp Mongo duy nhất, và bạn có thể sử dụng nó trong mọi yêu cầu"Tạo một tài liệu tham khảo tĩnh so với một singleton

Sử dụng một bản sao đơn lẻ có vẻ giống như một singleton.

Ở những nơi khác cho một thư viện khác, tôi đã đọc hướng dẫn nói rằng tôi nên tạo tham chiếu tĩnh vì nó là an toàn chỉ.

Ai đó có thể giải thích sự khác biệt giữa một singleton và tạo tham chiếu tĩnh không?

Vì vậy, các mã thực tế mà tôi cần phải nhanh chóng hoặc tĩnh hoặc thông qua một singleton sẽ là:

Mongo m = new Mongo("localhost" , 27017); 

Ai đó có thể giải thích cả hai phương pháp và sự khác biệt cơ bản nếu có?

Trả lời

2

Singleton là một mô hình thiết kế , nơi bạn có một thể hiện của một đối tượng chia sẻ giữa các phần còn lại của mã của bạn. Biến tĩnh là một tính năng ngôn ngữ Java .

Để triển khai Singleton, bạn thường sử dụng các biến tĩnh.

3

Bạn có 3 vấn đề: singleton, tham chiếu tĩnh và an toàn chỉ.

Bạn có một singleton nếu bạn chỉ có thể tạo một phiên bản của một lớp. Điều đó rất hữu ích vì mọi thứ sẽ trở nên lộn xộn nếu bạn có hai phiên bản của Mongo đang chạy. Tuy nhiên, bạn không thể triển khai mẫu thiết kế singleton cho Mongo trong mã của mình: bạn có thể gọi new Mongo() ở bất cứ đâu bạn muốn và tạo bao nhiêu trường hợp tùy thích. Bạn chỉ cần cẩn thận bạn không làm như vậy, nhưng nó không phải là rất khó.

Để thực hiện một singleton, nhà thiết kế lớp rất thường xuyên sẽ sử dụng một tham chiếu tĩnh như sau:

public class MyClass { 
    private static final MyClass SINGLETON = new MyClass(); 

    private MyClass() {...} // !!private, not accessible 

    public MyClass getSingleton() { return SINGLETON; } 
} 

Và bạn sẽ chỉ bao giờ có một trường hợp duy nhất của MyClass kể từ khi các nhà xây dựng là tư nhân và cách duy nhất để có một phiên bản là thông qua MyClass.getSingleton(). Rõ ràng nhà thiết kế Mongo sẽ phải thiết kế lớp Mongo như vậy; không có gì bạn có thể làm để làm cho nó một singleton.

Theo như an toàn luồng có liên quan, tôi không thấy liên kết với singleton. Một lớp singleton phải được thực hiện an toàn thread: nếu nhiều chủ đề thay đổi và đọc trạng thái của một singleton, bạn cần đồng bộ hóa thích hợp để đảm bảo tất cả các luồng đều thấy cùng một giá trị. Tôi không biết Mongo, nhưng tôi cá là nó là một lớp an toàn.

+0

Mongo an toàn chỉ và là một nhóm kết nối, tôi chỉ cần tạo một cá thể đơn, vì vậy một cá thể tĩnh là cách để đi? – codecompleting

+2

@codecompleting Có, một nơi nào đó trong lớp chính của bạn giao dịch với Mongo bạn nên có 'private static final Mongo mongo = new Mongo (" localhost ", 27017);' và chắc chắn rằng bạn không tạo một Mongo khác. Nếu bạn có một thiết kế đối tượng tốt, các lớp khác sẽ không bao giờ truy cập trực tiếp vào 'mongo'; nếu bạn cần các lớp khác để truy cập vào 'mongo', bạn có thể tạo phương thức' getMongo() 'trong lớp chính của bạn. – toto2

0

Sử dụng mẫu Singleton trên một đối tượng nếu bạn chỉ muốn truyền xung quanh một cá thể đơn lẻ của đối tượng này cho các đối tượng và phương thức khác cần sử dụng cá thể đơn lẻ này. Sử dụng tham chiếu tĩnh nếu bạn chỉ muốn sử dụng lớp của đối tượng một cách tĩnh (tức là tham chiếu tĩnh).

0

Nếu chỉ có một lớp đang sử dụng đối tượng đơn lẻ của bạn thì không có sự khác biệt rõ ràng về số đối tượng được tạo.

Giả sử bạn cần một đối tượng của classASing sử dụng Singleton cách tiếp cận

ClassASing { 
    private static ClassASing obj = new ClassASing(); 
    private ClassAsing(){...} 
    public static ClassASing getNewObject(){ 
      return obj; 
    } 
} 

Sử dụng Singleton cách tiếp cận

ClassB{ 
    private ClassASing singObj = ClassASing.getNewObject(); 
} 
  • dù có bao nhiêu trường hợp của ClassB tạo tất cả trong số họ sẽ được sử dụng cùng một đối tượng của ClassASing

sử dụng static ref erence

ClassB{ 
    private static ClassA sObj = new ClassA(); 
} 

* dù có bao nhiêu trường hợp của ClassB tạo tất cả trong số họ sẽ được sử dụng tài liệu tham khảo cùng trỏ đến cùng một đối tượng.

Không có nhiều khác biệt ở đây 1 đối tượng đang được sử dụng trong cả hai trường hợp.

Bây giờ nếu bạn xem xét một sencario khác mà bạn cần đối tượng trong hai lớp học của bạn.

phương pháp singleton

ClassB1{ 
      private ClassASing singObj1 = ClassASing.getNewObject(); 
     } 

ClassB2{ 
      private ClassASing singObj2 = ClassASing.getNewObject(); 
     } 
  • dù có bao nhiêu trường hợp của ClassB1 tạo tất cả trong số họ sẽ được sử dụng cùng một đối tượng của ClassASing
  • dù có bao nhiêu trường hợp của ClassB2 tạo tất cả trong số họ sẽ được sử dụng cùng một đối tượng ClassASing mà ClassB1 đang sử dụng để chỉ một đối tượng ClassASing

phương pháp tham chiếu tĩnh

ClassB1{ 
    private static ClassA sObj1 = new ClassA(); 
} 

ClassB2{ 
    private static ClassA sObj2 = new ClassA(); 
} 
  • dù có bao nhiêu trường hợp của ClassB1 tạo tất cả trong số họ sẽ được sử dụng tài liệu tham khảo cùng sobj1 trỏ đến cùng một đối tượng
  • dù có bao nhiêu trường hợp của ClassB2 tạo tất cả trong số họ sẽ được sử dụng cùng một tham chiếu sobj2 trỏ đến cùng một đối tượng nhưng đối tượng này khác với đối tượng được tạo trong ClassB1 vì vậy bây giờ bạn có hai đối tượng của ClassA.
+0

tha thứ cho tôi vì các lỗi cú pháp :) – Sudeep

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