2009-03-09 32 views
7

Singleton chắc chắn là một trong những mẫu bị lạm dụng và lạm dụng nhiều nhất. Nhiều người trong chúng ta đã bị nhiễm Singletonitis tại một thời điểm này hay cách khác. Thật kỳ lạ, người anh em họ gần gũi của nó Monostate ít nổi tiếng hơn và ít được sử dụng hơn. Ý kiến ​​của bạn về Monostate là gì? Tốt hay chỉ là ác? Nó là một lựa chọn tốt hơn để sử dụng Singleton? Bạn cũng sẽ không khuyến khích sử dụng nó như bạn làm với Singleton?Là Monostate người anh em họ tốt của Singleton ác?

+0

Chăm sóc để mô tả một trong hai mẫu để chúng tôi có thể thảo luận chính xác hơn? – Karl

Trả lời

5

cách không sử dụng các mẫu chỉ vì?

cập nhật: lạm dụng singleton xảy ra vì mọi người thêm mô hình bằng cách biện minh. Nó thường thêm ràng buộc tùy ý để không có lợi ích. bằng cách sử dụng monostate w/o biện minh có lẽ ít có hại, nhưng không có lý do chính đáng hơn. nếu vũ trụ sẽ không sụp đổ nếu có nhiều hơn một thể hiện, hơn là không thực thi nó với một mẫu - chỉ cần tạo một cá thể.

+0

Tôi không đồng ý. Nếu phần mềm là để phát triển thành một định dạng khối xây dựng thực, thì chúng ta cần chuẩn hóa cách mọi thứ được thực hiện, tương tự như cách các công cụ cấu trúc đã tiêu chuẩn hóa các phần khác nhau của cầu hoặc thiết kế tòa nhà. Các mẫu nên luôn được sử dụng để tự cuộn nếu có thể. –

+1

Câu hỏi không gợi ý rằng người ta nên sử dụng mẫu cho sake.Pattern không phải là một công cụ, nó là cùng một chủ đề xảy ra một lần nữa và một lần nữa trong xây dựng phần mềm.Nếu bạn xác định một mẫu trong thiết kế mã hàng ngày của bạn và biết ưu điểm của nó/nhược điểm, nó sẽ giúp bạn tạo ra phần mềm tốt hơn. – Boon

+0

"Không thực thi với nó với một mẫu" có vẻ như là một trong hai cách chúng tôi đang thực thi nó với một mẫu - trong trường hợp của bạn là mô hình "chỉ tạo một cá thể". Việc tạo một cá thể duy nhất không phải là miễn phí, có nghĩa là các phương thức hoặc chữ ký phương thức sẽ cần phải được thêm vào để truyền thông tin được chia sẻ xung quanh. – Boon

4

Tại sao bạn giả định rằng mọi người sẽ không khuyến khích sử dụng Singletons? Làm cho khái quát hóa sâu rộng về Singletons cũng giống như việc khái quát hóa về gotos, các biến toàn cục và vân vân. Có một nơi cho tất cả chúng. Không một thứ nào trong số này là "ác", và việc lạm dụng chúng không làm cho chúng trở nên tồi tệ khi sử dụng, điều đó có nghĩa là chúng cần được sử dụng đúng cách.

+2

Mọi người * làm * khuyến khích Singletons, đến mức Google có công cụ xóa chúng khỏi bất kỳ mã Java nào do nhân viên của họ viết! Họ tất nhiên có cách sử dụng của họ (chủ yếu là bộ nhớ đệm/xử lý tài nguyên) nhưng khi đối mặt với nó, họ là các biến toàn cầu và họ làm cho mã thử nghiệm là một cơn ác mộng. – rjh

+0

Tôi chưa bao giờ gặp vấn đề khi thử nghiệm đơn. Điều gì khiến họ trở nên ác mộng? –

+0

Ditto - hầu hết các tính năng/mẫu/chức năng có thể bị lạm dụng nếu sử dụng không chính xác; nó không làm cho họ vốn có 'ác'. – RobS

1

Thỏa thuận với Monostate là bạn cần phải biết ít hơn về việc triển khai đối tượng để sử dụng nó. Nói cách khác, bạn lưu một vài tổ hợp phím vì bạn không phải gọi phương thức getInstance (Singleton s = Singleton :: getInstance; s.Method();) để tham chiếu đến đối tượng, bạn chỉ cần sử dụng các cấu trúc ngôn ngữ bình thường (Monostate ms; ms.Method();). Một dòng tiền phạt thực sự.

Mỗi cấu trúc ngôn ngữ lập trình có thể được gắn nhãn là điều ác vì mọi sự co rút ngôn ngữ lập trình đều có thể bị lạm dụng.

Khi được sử dụng một cách hợp lý, tôi không thấy ai là "xấu" hoặc "tốt".

4

Vấn đề lớn nhất tôi có với Monostate là nó có thể dẫn đến sự nhầm lẫn về một phần của những người sử dụng nó. Nói chung, nếu bạn tạo một thể hiện mới của một đối tượng, bạn mong đợi nó chỉ là, một cá thể mới, với trạng thái và vòng đời của chính nó. Tôi thường xem xét hành vi bất ngờ là một điều xấu, vì vậy tôi thích singleton, chỉ vì bạn biết những gì bạn nhận được khi bạn sử dụng nó. Đối với bất kể mẫu có phải là ác hay không, những người độc thân có xu hướng bị lạm dụng, nhưng sau đó thực hiện tất cả các mẫu khác, chuyển đổi câu lệnh, cho vòng lặp hoặc bất kỳ thứ gì khác mà bạn quan tâm.

2

Dưới đây là một đoạn trích từ trang 127 của mẫu thiết kế: Các thành phần của phần mềm hướng đối tượng tái sử dụng được bởi Gamma, Helm, Johnson và Vlissides.

Sử dụng mẫu Singleton khi

  • phải có chính xác một thể hiện của một lớp, và nó phải được tiếp cận với khách hàng từ một điểm truy cập nổi tiếng
  • khi dụ duy nhất nên được mở rộng bởi subclassing và khách hàng sẽ có thể sử dụng một cá thể mở rộng mà không cần sửa đổi mã của họ

Nó thực sự làm cho độc ác chỉ vì họ bị lạm dụng và hiểu lầm?

+0

có. –

+0

không. – Skurmedel

5

Theo định nghĩa này của Monostates, là ghi chú này: "Monostates là xấu xa trong cùng một cách mà SingletonsAreEvil"

Tôi không nhất thiết phải đồng ý. Tiền đề cơ bản là Singletons và Monostates là các biến toàn cầu, và vì Globals là ác, nên cũng phải là Singletons và Monostates.

Vấn đề với dòng lý luận này là nó không tính đến WHY globals là tà ác. Globals là ác chủ yếu bởi vì chúng là các biến có thể được truy cập bên ngoài phạm vi cục bộ vô tình, tương tự như cách ngôn ngữ không gõ thường cho phép tạo các biến đơn giản bằng cách tham chiếu chúng.

Singletons và Monostates không thể gây ra cùng một loại vấn đề, bởi vì hầu như không thể "vô tình" tham chiếu đến một static toàn cầu, gọi phương thức instance của nó, sau đó sử dụng cá thể.

Nói cách khác, hình cầu là ác vì chúng gây ra những vấn đề tinh tế và khó nhìn thấy. Singletons và Monostates không gây ra cùng một loại vấn đề, vì vậy tôi không thấy chúng là ác vì cùng lý do, đó là nơi mà hầu hết mọi người dường như đi sai trong lập luận này.

Bây giờ, có thể đơn độc và độc tài gây ra các loại vấn đề khác không? Chắc chắn rồi. Rõ ràng, người TDD ghét họ vì họ khó kiểm tra chính xác với thử nghiệm tự động. Ok, tốt, nhưng đối với những người không sử dụng TDD, những vấn đề đó không tồn tại.

Tất nhiên những người độc thân có thể bị lạm dụng. Những người sử dụng chúng đơn giản để tránh việc vượt qua một cá thể xung quanh đang lợi dụng chúng. Tôi nghĩ rằng Monostates là tốt hơn cho điều đó hơn là một singleton.

Nhiều người đề xuất các mẫu nhà máy thay vì những người độc thân, nhưng tôi cảm thấy rằng các nhà máy chỉ là máy phát điện singleton ưa thích. Không, không có phương thức "instance" tĩnh nào, nhưng về cơ bản nó cũng làm điều tương tự (khi một nhà máy tạo ra một đối tượng cá thể đơn). Factory.Create không khác gì Singleton.Instance.

EDIT:

Một khía cạnh của Singletons và Monostates đó là so sánh với Globals là họ được chia sẻ, và do đó không đề an toàn. Trong khi đây là một mối quan tâm nếu bạn có kế hoạch để làm các ứng dụng đa luồng, nếu bạn biết điều này bạn có thể thực hiện các bước để serialize quyền truy cập vào các đối tượng được chia sẻ. Vì vậy, đây có lẽ là khu vực duy nhất, nói chung, cả ba loại có thể được coi là gây ra rắc rối.

+0

Cũng nói. Một điều mặc dù, các nhà máy không nhất thiết phải là máy phát điện singleton. Trong thực tế, hầu hết các nhà máy thời gian được sử dụng để tạo ra cá thể lớp thực tế. – Boon

+0

Đó là lý do tại sao tôi nói "khi một nhà máy tạo ra một đối tượng thể hiện đơn lẻ là". –

+0

99% thời gian khi nhà máy được sử dụng, nó được sử dụng làm hàm tạo ảo (ví dụ: nó trả về một trong các cá thể của lớp con dựa trên id được truyền vào), không phải là máy phát singleton. Vì vậy, Factory.Create là hầu như luôn luôn khác nhau từ Singleton.Instance. – Boon

7

Um, monostate Singleton ... vì vậy nó có cùng vấn đề tương tự.

  • thử nghiệm
  • ẩn phụ thuộc
  • cứng nhắc
  • an toàn thread
  • trạng thái toàn cầu làm cho nó khó khăn để đảm bảo tính đúng đắn
+0

Điều đó tổng hợp nó một cách độc đáo. Cả Monostate * cũng không * Singleton là một ý tưởng hay nói chung. – Randolpho

+3

Monostate không giống như singleton hoặc tôi sẽ không đặt ra câu hỏi này. https://segueuserfiles.middlebury.edu/xp/SingletonAndMonostate.pdf – Boon

+0

Để phân biệt singleton và monostate, bài viết này dừng lại ở các kỹ thuật - hiệu suất, đa hình và cú pháp - tất cả đều cụ thể cho việc triển khai Java. Nó không giải quyết sự khác biệt về khái niệm giữa singleton và monostate, bởi vì không có sự khác biệt. –

1

Làm thế nào về một lớp học với một trường hợp duy nhất, nhưng không toàn cầu quyền truy cập:

public class SingleInstance 
{ 
    private static boolean exhausted = false; 

    public SingleInstance() 
    { 
     if (exhausted) 
     { 
      throw new IllegalStateException("only one instance allowed"); 
     } 
     exhausted = true; 

     [...] 
    } 

    [...] 
} 

Điều này tránh được các vấn đề của Singleton và MonoState, trong khi nó thực thi và truyền đạt rõ ràng rằng chỉ có một ví dụ.

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