2008-12-09 35 views

Trả lời

10

Điều duy nhất dường như ngay lập tức với tôi là một lớp tĩnh về cơ bản chỉ là một tập hợp các hàm scoped (một cách rõ ràng) tránh "phương pháp" ở đây) và một singleton vẫn là thứ bạn có thể khởi tạo, ngay cả khi bạn chỉ có thể có 1. 1> 0.

Bạn có thể truyền một singleton làm đối số cho một đối tượng của một giao diện nhất định , bạn không thể vượt qua một lớp tĩnh bất cứ nơi nào (ngoại trừ thông qua một số thủ đoạn gian trá phản ánh)

2

Nó không chính xác tương đương. Ví dụ, bạn có thể chuyển một tham chiếu đến một cá thể singleton như một đối số, mà bạn không thể làm với một lớp tĩnh vì không có một cá thể nào.

Bạn có ý nghĩa gì với "nguy hiểm"?

+0

có lẽ nguy hiểm là sai cụm từ. tôi đã tự hỏi về sự khác biệt. tôi cho rằng thừa kế cũng là một vấn đề ... – spender

0

Không chắc về C#, nhưng trong C++ một đối tượng tĩnh sẽ được khởi tạo khi nó được khởi tạo, và bạn không có kiểm soát trực tiếp trên đó (đặc biệt là trong các ứng dụng đa luồng). Vì vậy, bạn cần một chức năng để gọi đối tượng của bạn, không chỉ gọi nó trực tiếp (trừ khi bạn muốn mã không thể chuyển đổi)

1

Như Robert Gould chỉ ra, bạn kiểm soát lỏng lẻo về xây dựng. Bạn cũng sẽ nhận được các vấn đề về xây dựng vốn ít rõ ràng hơn. Các lớp tĩnh nhanh chóng kết thúc với các khối khởi tạo tĩnh. Các khối này được gọi là lần đầu tiên ai đó tham chiếu đến loại của bạn và thứ tự này có thể không được xác định rõ như bạn muốn nghĩ. Vì vậy, thứ tự chạy của các trình khởi tạo tĩnh này có thể thay đổi mà không cần bạn lập kế hoạch như vậy và có thể gây ra các lỗi lạ.

0

Như Robert đã nói trước đó, việc khởi tạo là một bất lợi chính của một lớp tĩnh. Lớp tĩnh thường sẽ được khởi tạo một cách lười biếng, vào giây phút cuối cùng có thể. Tuy nhiên, bạn mất quyền kiểm soát đối với hành vi chính xác và các hàm tạo tĩnh là chậm.

Các lớp tĩnh thường được sử dụng để giữ dữ liệu chung. Và dữ liệu toàn cầu tạo ra sự phụ thuộc ngầm giữa các đối tượng/lớp khác của bạn. Vì vậy, bạn phải cẩn thận khi thay đổi "đối tượng toàn cầu" này. Có thể phá vỡ ứng dụng của bạn.

+0

Trên thực tế, trừ khi có một hàm tạo tĩnh (trái ngược với các biến khởi tạo biến tĩnh), kiểu có thể sẽ được khởi tạo sớm hơn nó cần phải có. –

+0

Nhà xây dựng tĩnh "Lười biếng" không phải là vấn đề. Bạn có thể thực hiện thủ tục Init tĩnh bằng tay thay vì constructor tĩnh. – macropas

+0

Ý định của tôi là không nói rằng "lười" là một vấn đề. Tên bí danh cho mẫu đơn là "Khởi tạo lười". Những gì tôi thường thấy là Singletons và/hoặc các lớp tĩnh được sử dụng như một sự thay thế cho các biến toàn cục. – TomTom

4

Trong nhiều cách, một lớp tĩnh và một singleton giống nhau. Một sự khác biệt lớn là một singleton có thể thực hiện một số giao diện, điều này là không thể với một lớp tĩnh. Ví dụ: Comparer<T>.Default/EqualityComparer<T>.Default cung cấp (qua giao diện) khả năng sử dụng mục khi sắp xếp/sử dụng từ điển.

Cũng có thể (mặc dù khó) để sử dụng một singleton với các khung tuần tự tiêu chuẩn hóa. Với một lớp tĩnh, bạn phải quản lý bất kỳ trạng thái kiên trì nào theo cách thủ công.

0

Trong ngữ cảnh triển khai singleton, không có bất kỳ mối nguy hiểm nào. Tôi thường làm tương tự, imlementing singletone thông qua lớp tĩnh. Một cách hợp lý, tham chiếu đối tượng là không cần thiết nếu nó là một mình và duy nhất.

+0

Tất nhiên, nếu không cần thiết trong việc thực hiện Giao diện hoặc serialization tiêu chuẩn. Tôi đồng ý với Marc Gravell – macropas

1

Mối nguy hiểm chính mà tôi có thể thấy với các lớp tĩnh là chúng khó khăn hơn nhiều khi giả lập khi viết các bài kiểm tra đơn vị. Với một singleton bạn có thể tạo ra nó theo cách mà bạn có thể tiêm một lớp khác vào vị trí của nó mà không kiểm tra chức năng cụ thể, với một lớp tĩnh này không phải là dễ dàng như vậy.