2011-08-04 29 views
6

Tôi thấy điều này khi sử dụng picocontainer. Họ nói rằng bạn phải tránh những người độc thân. vì mẫu Singleton làm cho nó hầu như không thể cho lớp (và có thể tất cả các lớp khác phụ thuộc vào nó) để có thể kiểm tra được. Nó rất khó để phân lớp, hoặc để tạo ra một đối tượng giả cho một lớp Singleton.Thử nghiệm đơn và phân lớp

Nhưng nếu bạn hoàn toàn cần, Có cách giải quyết nào cho sự cố kiểm tra và phân lớp không?

Trả lời

5

Điều gì gây khó khăn cho việc thử nghiệm đơn là mã thực thi singleton-ness của họ (có nghĩa là bản liệt kê public static MySingleton getInstance() {...}). Sử dụng một container đảo ngược-of-kiểm soát, như PicoContainer hoặc Guice hoặc mùa xuân, loại bỏ rằng mối quan tâm từ đối tượng, vì vậy bây giờ:

cộng tác viên
  • Nó có thể được khởi tạo và có cắm vào nó trong các thử nghiệm mà không có một vấn đề.

  • Mã gọi một singleton không phải biết lớp học đang tìm kiếm (mà nó cần phải biết nếu nó phải gọi một phương thức tĩnh).

Tôi giải thích lời khuyên trên trang web của picocontainer tương tự như vậy. Những gì họ đang nói với bạn là, hãy để vùng chứa của chúng tôi quản lý phạm vi các thành phần của bạn cho bạn, không phải cố định mã thực thi phạm vi vào chúng.

+0

Hoàn toàn đúng - IOC là cách để thực hiện công cụ này –

1

Nếu bạn phải có độc thân:

  1. Có một giao diện mô tả từng singleton
  2. Tiếp cận độc thân của bạn từ một toàn cầu/singleton ServiceLocator
  3. Chuyển các trường hợp đăng ký tại ServiceLocator trong thử nghiệm

Ví dụ:

interface IBankApi 
{ 
    public void MakeDeposity(int accountNumber, int dollarAmount); 
    // ... 
} 

public class RealBankApi : IBankApi { ... } 

// startup code 
serviceLocator.Register<IBankApi>(new RealBankApi()); 

// code using the API 
serviceLocator.Resolve<IBankApi>().MakeDeposit(...); 

// test code setup 
class FakeBankApi : IBankApi { ... } 
serviceLocator.Register<IBankApi>(new FakeBankApi()); 
1

Sử dụng IOC (đảo ngược kiểm soát) thay vì sử dụng đơn đầu tiên khi sử dụng lần đầu tiên cũng có lợi cho các lý do khác.

Singleton-initialisation có thể bị (nổi tiếng) từ các vấn đề đa luồng, trong đó hai chủ đề cố gắng truy cập nó lần đầu tiên cùng một lúc. Truy cập tiếp theo có thể được đồng bộ hóa chính xác nhưng việc đầu tiên khó thực hiện hơn nhiều.

Một ưu điểm lớn khác mà tôi đã tìm thấy khi sử dụng IOC là khi có lỗi xảy ra trong quá trình khởi tạo. Bạn không muốn điều này xảy ra trong "lần sử dụng đầu tiên", bạn muốn biết về sự thất bại này ở giai đoạn đầu và chắc chắn sẽ dễ dàng xử lý lỗi theo cách này. Cuối cùng, liên quan đến thử nghiệm, IOC cung cấp mô hình hoàn hảo để cô lập các thành phần, thay thế chúng khi cần thiết và kết hợp các kết hợp khác nhau một cách linh hoạt hơn, do đó cung cấp khai thác hoàn hảo cho cả thử nghiệm đơn vị và tích hợp cũng như một cơ chế rollback tốt mà không thực sự phải hoàn nguyên bất kỳ mã nào.

Lý do chung thường được sử dụng đơn giản không phải là cho một-ness nhưng cho toàn cầu-Ness. Nếu dự án của bạn được quản lý đúng, bạn có một đối tượng toàn cầu duy nhất mà tất cả những người khác "đăng ký" (do đó mô hình IOC của bạn bị treo) và có sẵn trên toàn cầu trong khi vẫn có thể cấu hình được.

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