Câu hỏi Sự khác nhau giữa lớp tĩnh và mẫu đơn?


Sự khác biệt thực sự (thực tế) tồn tại giữa một lớp tĩnh và một mẫu đơn là gì?

Cả hai có thể được gọi mà không có instantiation, cả hai chỉ cung cấp một "Instance" và cả hai đều không an toàn thread. Có sự khác biệt nào khác không?


1493
2018-02-06 08:13


gốc


Tùy thuộc vào việc triển khai ngôn ngữ và các mẫu sử dụng của bạn, Singleton có thể là kém hiệu quả hơn do chi phí gọi điện getInstance() phương pháp mỗi lần bạn muốn sử dụng nó (mặc dù có thể trong hầu hết các trường hợp không thành vấn đề). - too much php
Có rất nhiều câu trả lời rồi. Nó thực sự là một singleton đối tượng ở đâu static các phương thức chỉ là các hàm, một thực thể không phải là OO. - fastcodejava
Phụ thuộc vào việc thực hiện .. csharpindepth.com/Articles/General/Singleton.aspx - VJAI
Có một sự khác biệt khi bạn muốn cho phép các bên thứ ba cung cấp việc thực hiện lớp. Trong trường hợp này, bạn thường cần một mẫu Nhà máy. Xem agiletribe.wordpress.com/2013/10/08/… - AgilePro
IMO câu trả lời này tóm tắt rất tốt stackoverflow.com/questions/14097656/… - Dave


Các câu trả lời:


Điều gì làm cho bạn nói rằng một singleton hoặc một phương pháp tĩnh không an toàn thread? Thông thường cả hai Nên được thực hiện để an toàn chỉ.

Sự khác biệt lớn giữa một singleton và một loạt các phương thức tĩnh là các singletons có thể thực hiện các giao diện (hoặc bắt nguồn từ các lớp cơ sở hữu ích, mặc dù nó ít phổ biến hơn, theo kinh nghiệm của tôi), vì vậy bạn có thể vượt qua singleton như thể nó là " thực hiện.


1044
2018-02-06 08:17



Vâng, nếu bạn thích nó, không phải là chủ đề an toàn, bạn phải làm cho chúng trở thành chủ đề an toàn, cả hai, vì vậy không có sự khác biệt ở đó. - Jorge Córdoba
Bạn có thể đưa ra một ví dụ về cái gì đó Là vốn là chủ đề an toàn, ngoài các loại bất biến? - Jon Skeet
Để Skeet: Mọi người nói rằng singleton không phải là threadsafe có nghĩa là một singleton được chia sẻ giữa các chủ đề không cần thiết mọi lúc, trong khi các đối tượng ngăn xếp được chia sẻ khi bạn cần chúng, điều đó có nghĩa là bạn không phải thực hiện đồng bộ hóa không cần thiết.
@Geek: Hãy tưởng tượng singleton thực hiện một giao diện Foovà bạn có phương pháp tham gia Foo như một tham số. Với thiết lập đó, người gọi có thể chọn sử dụng singleton như triển khai - hoặc họ có thể sử dụng triển khai khác. Phương pháp này được tách ra từ singleton. So sánh điều đó với tình huống mà lớp chỉ có các phương thức tĩnh - mọi đoạn mã muốn gọi những phương thức đó được kết hợp chặt chẽ với lớp, vì nó cần xác định lớp nào chứa các phương thức tĩnh. - Jon Skeet
@AmirBareket: Nó không phải là một singleton theo mẫu thiết kế singleton mặc dù - nếu lớp chính nó cho phép nhiều trường hợp được tạo ra, nó không phải là một IMO singleton, bất kể những gì nhà máy làm. - Jon Skeet


Câu trả lời thực sự là của Jon Skeet, trên một diễn đàn khác tại đây.

Singleton cho phép truy cập vào một đĩa đơn   trường hợp đã tạo - ví dụ đó (hoặc   thay vào đó, một tham chiếu đến trường hợp đó)   có thể được chuyển như một tham số cho   phương pháp và được coi là bình thường   vật.

Một lớp tĩnh chỉ cho phép tĩnh   phương pháp.


404
2018-02-06 08:21



Tại sao bạn sẽ vượt qua Singleton như một tham số, tuy nhiên, nếu bạn có thể truy cập cùng một cá thể từ bất kỳ đâu bằng cách gọi phương thức getInstance () tĩnh? - Henrique Ordine
@HenriqueOrdine Vì vậy, nó có thể phù hợp với mã hiện tại và cung cấp một giao diện?
@HenriqueOrdine Họ đang nói về lớp tĩnh, không phải là một lớp với các phương thức tĩnh. Lớp tĩnh không thể được khởi tạo. Tuy nhiên, nếu bạn vượt qua một thể hiện của một lớp (không tĩnh) có chứa các phương thức tĩnh, bạn không thể gọi các phương thức tĩnh trên một cá thể. - Goran
Lớp tĩnh là gì? Ít nhất trong Java, không có thứ như vậy. - Henrique Ordine
@Goran Tôi bước đầu rất bối rối bởi từ ngữ của bạn. Bạn nói "bạn không thể gọi các phương thức tĩnh trên một thể hiện". Tôi đọc đó là "nếu bạn có một tham chiếu đến một đối tượng instantiated, bạn không thể gọi bất kỳ phương pháp tĩnh nó có thể có." Đó là tất nhiên, không chính xác. Sau khi đọc nó một lần nữa một vài lần tôi nghĩ rằng bạn có nghĩa là "từ bên trong phương pháp tĩnh bạn không thể truy cập các đối tượng không tĩnh trong lớp" đó là chính xác. Bạn muốn làm rõ điều đó đối với bất kỳ ai mới về những khái niệm này, những người đi qua câu trả lời này và đọc nhận xét của bạn. - Andrew Steitz


  1. Các đối tượng Singleton được lưu trữ trong Heap, nhưng các đối tượng tĩnh được lưu trữ trong cây rơm.
  2. Chúng ta có thể bản sao (nếu nhà thiết kế không cho phép nó) đối tượng singleton, nhưng chúng ta không thể nhân bản đối tượng lớp tĩnh .
  3. Các lớp Singleton theo OOP (nguyên tắc hướng đối tượng), các lớp tĩnh không.
  4. Chúng ta có thể thực hiện một interface với lớp Singleton, nhưng phương thức tĩnh của lớp (hoặc ví dụ: C # static class) không thể.

325
2017-09-11 10:22



Câu thứ hai là sai. Chúng ta không thể sao chép đối tượng Singleton. Singleton thực hiện phải từ chối này. Nếu bạn thực sự có thể sao chép Singleton, nó không phải Singleton. - Alexander Yancharuk
Đây là câu trả lời không đúng cho Java: cả singleton lẫn static đều không sử dụng stack. - AgilePro
# 1 không quan trọng. # 2 mô tả việc triển khai lỗi. # 3 là hoàn toàn không hợp lý. - Casey
Làm cách nào để đối tượng tĩnh có thể được lưu trữ trong ngăn xếp? Khung stack mới được tạo ra khi bạn gọi một phương thức, nó lưu trữ các biến cục bộ của phương thức, khung ngăn xếp này được loại bỏ khi phương thức trả về, và các biến cục bộ đó bị mất. Chồng chắc chắn là nhanh, nhưng nó không thích hợp để lưu trữ các đối tượng tĩnh. - mike_m
Tôi không thể hiểu số lượng upvotes trên này. 1) Tại sao Singleton phải được lưu trữ trong ngăn xếp? Trong các ngôn ngữ được quản lý như C # hoặc dữ liệu Java được lưu trữ trong một vùng được quản lý, ngoại trừ các biến / tham số của phương thức cục bộ. 2) Nếu bạn có thể sao chép nó, sau đó nó không phải là một singleton thực hiện đúng. 3) Singleton được biết đến như một mô hình chống OOP; tức là một cái gì đó mà bạn nên tránh nếu có thể. 4) Đây là điều duy nhất đúng. - Groo


Mẫu Singleton có nhiều ưu điểm so với các lớp tĩnh. Đầu tiên, một singleton có thể mở rộng các lớp và thực hiện các giao diện, trong khi một lớp tĩnh không thể (nó có thể mở rộng các lớp, nhưng nó không kế thừa các thành viên cá thể của chúng). Một singleton có thể được khởi tạo một cách lười biếng hoặc không đồng bộ trong khi một lớp tĩnh thường được khởi tạo khi nó được nạp lần đầu tiên, dẫn đến các vấn đề về trình nạp lớp tiềm năng. Tuy nhiên, lợi thế quan trọng nhất, mặc dù, là các singletons có thể được xử lý đa hình mà không buộc người dùng của họ giả định rằng chỉ có một cá thể.


122
2018-02-06 08:30



1 cho điểm tốt, thực dụng. Mẫu Singleton bị lạm dụng nói chung, nhưng có một vài tình huống mà nó phù hợp. Xem thêm: agiletribe.wordpress.com/2013/10/08/… - AgilePro
1 cho chỉ ra khởi tạo mong muốn của các lớp tĩnh. - Arpit Khandelwal
Bạn đúng về lợi thế của việc đa hình. Đây là điểm quan trọng nhất - Ahmad
Lớp tĩnh lồng nhau có thể thực hiện giao diện. Hãy thử mã hóa nó, sẽ hoạt động. Tôi có thể biên dịch mã mà không có bất kỳ lỗi nào. - nanosoft


static các lớp học không nên làm bất cứ điều gì cần nhà nước, nó rất hữu ích cho việc đưa bó các chức năng với nhau, tức là Math (hoặc là Utils trong các dự án). Vì vậy, tên lớp chỉ cung cấp cho chúng tôi một đầu mối, nơi chúng tôi có thể tìm thấy các chức năng và không có gì hơn.

Singleton là hình mẫu yêu thích của tôi và sử dụng nó để quản lý một cái gì đó tại một điểm duy nhất. Nó linh hoạt hơn static các lớp học và có thể duy trì trạng thái. Nó có thể thực hiện các giao diện, kế thừa từ các lớp khác và cho phép thừa kế.

Quy tắc của tôi để lựa chọn giữa static và singleton:

Nếu có nhiều chức năng nên được giữ lại với nhau, thì static là sự lựa chọn. Bất kỳ điều gì khác cần truy cập một số tài nguyên, có thể được triển khai singleton.


56
2017-12-30 20:55



Tại sao các lớp tĩnh không làm bất cứ điều gì cần lưu trạng thái? - Trisped
@ Trisped: Bạn không có sự kiểm soát chính xác nào về việc khởi tạo cũng như quyết toán. - Xaqron
Jon skeet đã trả lời tốt. Điểm khác biệt không tốt của nó. - Gul Md Ershad
bạn mất tôi ở "Singleton là mẫu yêu thích của tôi". Singleton là một góc sắc bén nên nó được coi là một hình mẫu chống lại cũng như một khuôn mẫu. Các lớp cũng có thể có trạng thái tĩnh, đó cũng là truy cập đơn, nếu bất kỳ trạng thái tĩnh nào là "truy cập đơn lẻ" nhiều hơn so với các bộ đơn vì hầu hết các triển khai singleton đều bị hỏng. bạn có thể sao chép singleton, trong khi tĩnh được may mắn bởi định nghĩa là duy nhất. - PoweredByRice
@KyleDelaney: Đơn giản State là sự kết hợp các thuộc tính khác nhau của một đối tượng thường thay đổi theo thời gian. Bạn có thể Google cho định nghĩa chính thức. - Xaqron


Lớp tĩnh: -

  1. Bạn không thể tạo cá thể của lớp tĩnh.

  2. Tự động nạp bởi thời gian chạy ngôn ngữ chung của Khuôn khổ .NET (CLR) khi chương trình hoặc không gian tên chứa lớp được nạp.

  3. Lớp tĩnh không thể có hàm tạo.

  4. Chúng ta không thể chuyển lớp tĩnh sang phương thức.

  5. Chúng ta không thể kế thừa lớp tĩnh đến một lớp tĩnh khác trong C #.

  6. Một lớp có tất cả các phương thức tĩnh.

  7. Hiệu suất tốt hơn (các phương thức tĩnh được liên kết trên thời gian biên dịch)

Singleton: -

  1. Bạn có thể tạo một thể hiện của đối tượng và sử dụng lại nó.

  2. Singleton instance được tạo lần đầu tiên khi người dùng yêu cầu.

  3. Lớp Singleton có thể có hàm tạo.

  4. Bạn có thể tạo đối tượng của lớp singleton và chuyển nó vào phương thức.

  5. Lớp Singleton không nói bất kỳ hạn chế nào của Inheritance.

  6. Chúng ta có thể vứt bỏ các đối tượng của một lớp singleton nhưng không thể bỏ qua lớp tĩnh.

  7. Phương pháp có thể được ghi đè.

  8. Có thể được nạp lười khi cần (các lớp tĩnh luôn được tải).

  9. Chúng ta có thể thực hiện giao diện (lớp tĩnh không thể thực hiện giao diện).


49
2018-06-01 11:42



Các lớp tĩnh có các hàm tạo: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx - Tomer Arazy
Có, tĩnh có thể có hàm tạo bên trong lớp đó. Điều này được gọi khi bất kỳ phương thức tĩnh nào trong lớp được gọi. - rahulmr
Đối với singleton trên thời gian biên dịch, nó được lưu trữ trong bộ nhớ HEAP nhưng nếu nó được instantiated một lần nó được lưu trữ trong STACK? - Luminous_Dev
@Luminous_Dev Không. Bất kỳ cá thể singleton nào là một cá thể đối tượng vào cuối ngày. Nó sẽ được lưu trữ trên heap mà không nghi ngờ gì. - RBT


Một lớp tĩnh là một lớp chỉ có các phương thức tĩnh, trong đó một từ tốt hơn sẽ là "các hàm". Phong cách thiết kế thể hiện trong một lớp tĩnh hoàn toàn là thủ tục.

Singleton, mặt khác, là một mô hình cụ thể cho thiết kế OO. Nó là một thể hiện của một đối tượng (với tất cả các khả năng vốn có trong đó, chẳng hạn như đa hình), với một quy trình tạo để đảm bảo rằng chỉ có một ví dụ của vai trò cụ thể đó trong toàn bộ vòng đời của nó.


48
2018-02-06 08:35



đa hình không đi vào chơi với những người độc thân
Vì vậy bạn nghĩ. Tôi nghĩ khác đi. ;) Ví dụ, hãy tưởng tượng một nhà máy đơn lẻ trả về một giao diện. Bạn biết bạn đang nhận được một ISingleton (và nó là cùng một mãi mãi) nhưng không nhất thiết phải thực hiện. - Morendil
Lớp tĩnh lồng nhau có thể có các phương thức cá thể, nó không bị giới hạn chỉ có các phương thức tĩnh .. Mã nó và bạn có thể thấy. - nanosoft
Trong các ngôn ngữ có mô hình đối tượng đẹp hơn (ví dụ: Ruby), các lớp cũng là các đối tượng. Khía cạnh "thuần túy thủ tục" của một lớp tĩnh là một hạn chế tùy ý được áp đặt bởi ngôn ngữ. - Max


Trong mẫu đơn, bạn có thể tạo singleton như một thể hiện của một kiểu có nguồn gốc, bạn không thể làm điều đó với một lớp tĩnh.

Ví dụ nhanh:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer

32
2018-02-06 08:16



Nó không thực sự là một mẫu đơn, trông giống như nhà máy với tôi. - vava
Không thực sự, sự khác biệt cơ bản giữa hai là Singleton sẽ "cache" đối tượng duy nhất của nó và tiếp tục quay trở lại (một tham chiếu đến) cùng một. Mẫu Nhà máy sẽ tạo các phiên bản mới. - Mystic
Sau đó, nó là proxy-singleton :) - vava
Hmm, tôi biết sự đa dạng của Singleton là MonoState. - Huppie
ví dụ là mẫu nhà máy - Rajavel D


Mở rộng trên Câu trả lời của Jon Skeet

Sự khác biệt lớn giữa một singleton và một loạt các phương thức tĩnh là các singletons có thể thực hiện các giao diện (hoặc xuất phát từ các lớp cơ sở hữu ích, mặc dù IME ít phổ biến hơn), vì vậy bạn có thể truyền xung quanh singleton như thể nó chỉ là một thực thi khác.

Singletons dễ làm việc hơn khi đơn vị kiểm tra một lớp. Bất cứ nơi nào bạn vượt qua singletons như là một tham số (constructors, setters hoặc phương pháp), bạn có thể thay thế một phiên bản giả hoặc stubbed của singleton.


22
2017-12-20 21:53



Tôi không nghĩ rằng bạn có thể trực tiếp thử một singleton. Bạn sẽ không phải khai báo một giao diện mà singleton và lớp mô hình thực hiện cả hai? - Ellen Spertus
@espertus Tại sao bạn không thể thử singleton của bạn? Ví dụ sử dụng mockito MySingleton mockOfMySingleton = mock(MySingleton.class). - Mike Rylander
bạn nói đúng, bạn có thể giả lập nó bằng các công cụ như mockito sử dụng sự phản chiếu. Tôi có nghĩa là bạn không thể giả lập nó trực tiếp bằng cách phân lớp và ghi đè các phương thức của nó. - Ellen Spertus
@espertus Tại sao không? Khi bạn khởi tạo đối tượng mà bạn đang thử nghiệm, bạn có thể thay thế việc triển khai lớp con của singleton của bạn bất cứ nơi nào bạn đã sử dụng bản gốc. Ví dụ: new ClazzToTest(mockSingleton); - Mike Rylander
Tôi đã không sử dụng Mockito, nhưng làm thế nào bạn có thể phân lớp một lớp có một nhà xây dựng tư nhân, đó là trường hợp cho người độc thân, ngoại trừ bằng cách sử dụng sự phản ánh? Các cuộc thảo luận liên quan: stackoverflow.com/questions/2302179/mocking-a-singleton-class  stackoverflow.com/questions/15939023/… - Ellen Spertus


Một ưu điểm khác của singleton là nó có thể dễ dàng được tuần tự hóa, có thể cần thiết nếu bạn cần lưu trạng thái của nó vào đĩa, hoặc gửi nó ở đâu đó từ xa.


20
2017-08-08 03:36





Tôi không phải là một nhà lý thuyết OO tuyệt vời, nhưng từ những gì tôi biết, tôi nghĩ rằng tính năng OO duy nhất mà các lớp tĩnh thiếu so với Singletons là tính đa hình. Nhưng nếu bạn không cần nó, với một lớp tĩnh, tất nhiên bạn có thể thừa kế (không chắc chắn về việc thực hiện giao diện) và dữ liệu và chức năng đóng gói.

Nhận xét của Morendil, "Phong cách thiết kế thể hiện trong một lớp tĩnh hoàn toàn là thủ tục" Tôi có thể sai, nhưng tôi không đồng ý. Trong các phương thức tĩnh, bạn có thể truy cập các thành viên tĩnh, mà sẽ chính xác giống như các phương thức singleton truy cập các thành viên cá thể đơn lẻ của chúng.

chỉnh sửa:
Tôi thực sự đang nghĩ rằng sự khác biệt khác là một lớp tĩnh là khởi tạo lúc bắt đầu chương trình * và sống trong suốt toàn bộ vòng đời của chương trình, trong khi một singleton được khởi tạo rõ ràng tại một thời điểm nào đó và cũng có thể bị phá hủy.

* hoặc nó có thể được khởi tạo ngay lần đầu tiên, tùy thuộc vào ngôn ngữ, tôi nghĩ vậy.


17
2017-08-16 15:54



Có, mọi người khác dường như bỏ qua thực tế là một lớp với các phương thức tĩnh cũng có thể có các trường tĩnh riêng tư mà nó vẫn có thể sử dụng để duy trì trạng thái (và hiển thị một số mã trong số đó bằng mã định vị công khai / getters). - user289463