2011-01-19 18 views
8

Tôi đã đọc bài viết Abstract Factory, Template Style của Jim Hyslop và Herb Sutter. Nhà máy này được thực hiện như một Singleton. Họ cung cấp một cách dễ dàng để đăng ký các lớp tự động với lớp helper RegisterInFactory.GenericFactory là Singleton

Bây giờ tôi đã đọc nhiều lần rằng nên tránh Singletons, một số thậm chí coi chúng là Anti-Patterns và chỉ có một vài trường hợp chúng hữu ích. Đây có phải là một trong số đó không? Hoặc là có một cách tiếp cận thay thế cung cấp một cách dễ dàng như vậy để autoregister lớp học?

+0

Tôi tò mò muốn biết bạn từ đâu đề cập đến "Singletons nên tránh" ... – YeenFei

+0

"Singletons nên tránh" giống như các biến toàn cục. Một nhà máy trừu tượng giống như một dịch vụ toàn cầu. Sau khi khởi tạo (Đăng ký) tất cả các khách hàng chỉ đọc từ nó (yêu cầu đối tượng). Tôi nghĩ Nhà máy Tóm tắt là một trong những trường hợp Singleton có ích. – hansmaad

+0

tức là http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used hoặc http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827. aspx – P3trus

Trả lời

2

Như từng loại chủ đề này, không có câu trả lời nào áp dụng cho mọi vấn đề. Một số người nói rằng singleton nên tránh khi chúng được sử dụng như một truy cập vào một dịch vụ. Nó là một sử dụng giống như việc sử dụng các biến toàn cầu. Bằng cách này bạn che giấu một thực tế mà bạn sử dụng dịch vụ X trong việc thực hiện của bạn:

// in header 
class MyUsefulClass 
{ 
    public: 
    void doSomethingUseful(); 
}; 

// in .cpp 
MyUsefulClass::doSomethingUseful() 
{ 
    // ... 
    MyWonderfulService::instance().doService1(); 
    // ... 
    MyWonderfulService::instance().doService2(); 
} 

Bạn tạo một khớp nối với MyWonderfulService rằng người dùng của lớp học của bạn không thể đoán. Hơn nữa, Bạn có thể không dễ dàng kiểm tra lớp hữu ích của bạn với một dịch vụ giả ...

Đó là lý do tôi thường thích dependancy inversion:

// in header 
class MyUsefulClass 
{ 
    public: 
    void setServiceToUse(MyService&); 
    void doSomethingUseful(); 

    // [...] 
}; 

// in .cpp 
MyUsefulClass::doSomethingUseful() 
{ 
    // ... 
    _myService->doService1(); 
    // ... 
    _myService->doService2(); 
} 

Bằng cách này thường được coi là tốt hơn như các khớp nối giữa lớp là nhẹ hơn. Tuy nhiên, đối với một số dịch vụ, được biết đến là được sử dụng rộng rãi trong một khuôn khổ, nó đơn giản hơn để sử dụng một singleton. Điều đó có ý nghĩa đối với một dịch vụ đơn lẻ là dịch vụ cung cấp cho bạn quyền truy cập vào tất cả các dịch vụ khác trong một khuôn khổ ví dụ^^ Nó thường được sử dụng cho các dịch vụ kỹ thuật như ghi nhật ký ví dụ.

my2c

Edit: Tôi đọc bài báo, như tập trung vào AbstractFactories, việc sử dụng một singleton là một bình thường, không phải là một quyết định thiết kế. Có thể hiểu được trong một bài báo mà bạn không muốn viết những thứ sẽ không giúp bạn đạt được điểm của mình.

+0

Vì vậy, để có autoregistration như được hiển thị trong bài viết tôi cần truy cập toàn cầu nhưng tôi không cần nó là trường hợp duy nhất. Một thay thế do đó sẽ được cung cấp nó như là một toàn cầu như std :: cout mà alows tôi sử dụng nó, nhưng doen't ngăn cản tôi sử dụng một thứ hai nếu cần thiết. Hoặc là có một cách thứ ba, có lẽ cách vượt trội để đạt được autoregistration này? – P3trus

+0

@ p3trus: Tôi sẽ thêm một ví dụ cụ thể vào câu trả lời của tôi khi tôi có thời gian ... Chỉ cần thử toàn cầu ngay bây giờ. Tôi personnaly sử dụng đảo ngược depandancy mọi lúc ... – neuro