2009-01-07 50 views
7

Trong báo cáo sơ lược của tôi, tôi càng ngày càng thấy kết quả thử nghiệm dựa trên mô hình với việc tiêm phụ thuộc. Nhiều người trong số các phụ thuộc là tĩnh, nhưng vì chúng tôi muốn thử nghiệm các phương pháp trong sự cô lập họ đang thay đổi với các thành viên dụ, như ví dụ sau:Các vấn đề về hiệu năng từ tiêm phụ thuộc

class ShortLivedThing { 
    IDependency1 dep1; 
    IDependency1 dep2; 
    IDependency1 dep3; 
    ... 

    int TheRealData; 

    // Constructor used in production 
    public ShortLivedThing() { 
    dep1 = new Dep1(); dep2 = new Dep2(); dep3 = new Dep3(); 
    } 

    // DI for testing 
    public ShortLivedThing(IDependency1 d1, IDependency2 d2, IDependency3 d3) { 
    dep1 = d1(); dep2 = d2(); dep3 = d3(); 
    } 
} 

Đổi lại phụ thuộc phần lớn thời gian có phụ thuộc khác và vân vân. Điều này dẫn đến sự khởi tạo của một đối tượng (chủ yếu là "tĩnh") mỗi khi thực hiện cuộc gọi phương thức bên ngoài các thử nghiệm. Mỗi đối tượng là rất nhỏ (chỉ là một vài con trỏ), nhưng hiệu ứng cây biến điều này thành một hit hiệu suất ngày càng tăng.

Chúng ta có thể làm gì với nó?

+0

Bạn có định hình mã sản xuất hoặc thử nghiệm của mình không? –

+0

Tôi đang lược tả mã sản xuất. Các thử nghiệm chạy nhanh vì chúng không xây dựng các phụ thuộc của các phụ thuộc. –

Trả lời

8

Dường như với tôi như bạn cần tận dụng các tính năng mà khung tiêm phụ thuộc thích hợp có thể cung cấp cho bạn. Không sử dụng logic xây dựng khác nhau để thử nghiệm/sản xuất.

Với mùa xuân, tiêm đơn chỉ được thực hiện khi khởi động vùng chứa. Việc tiêm mẫu thử được thực hiện mỗi lần. Toàn bộ hệ thống dây điện cũng được thực hiện mỗi khi bạn chạy thử nghiệm đơn vị, nếu nó đang được nối dây. Vì vậy, các bài kiểm tra đơn vị lược tả thường không phải là một ý tưởng hay.

Có thể bạn đang sử dụng quá ít phạm vi đơn và phạm vi nguyên mẫu quá nhiều? (Prototype = dụ mới mỗi lần)

Những điều tốt đẹp về tiêm mùa xuân là bạn có thể sử dụng phạm vi proxy, có nghĩa là đồ thị đối tượng của bạn có thể trông như thế này:

A Singleton 
| 
B Singleton 
| 
C Prototype (per-invocation) 
| 
D Singleton 
| 
E Session scope (web app) 
| 
F Singleton 

Và mỗi yêu cầu sẽ chỉ tạo ra 1 ví dụ của C và một phiên bản E trên mỗi phiên. A, B, D và F là những người độc thân. Nếu nó không phải là một webapp bạn không có phạm vi phiên theo mặc định, nhưng bạn cũng có thể làm cho phạm vi tùy chỉnh (một "Window" phạm vi âm thanh mát mẻ cho một ứng dụng máy tính để bàn cửa sổ). Đầu mối ở đây là bạn có thể "giới thiệu" phạm vi ở mọi cấp độ, có hiệu quả bạn có thể có mười lớp đối tượng đơn lẻ và tất cả của một phiên bất ngờ đột ngột xuất hiện. (Điều này thực sự có thể cách mạng hóa cách bạn thực hiện một số tính năng cắt ngang trong kiến ​​trúc phân lớp nhưng đó là một câu chuyện khác)

Điều này thực sự tạo ra đối tượng tối thiểu có thể trong mô hình DI.

Mặc dù đây là Spring for Java, tôi tin rằng một số khung công tác DI khác sẽ hỗ trợ các tính năng tương tự. Có lẽ không phải những người tối giản nhất.

+0

F có được đối tượng E không? Nếu vậy, làm thế nào điều này làm việc với nhiều người dùng? –

+0

Tôi đã suy nghĩ từ trên xuống dưới, và D được cấp cho E. Dynamic proxy hoặc cglib thực hiện phép thuật. – krosenvold

+0

Và có, nó hoạt động thực sự tốt với nhiều người dùng. 300 ký tự được slighlty nhỏ. Xem http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes – krosenvold

1

Làm cách nào để chuyển tiếp tham chiếu?

0

Điều tốt nhất tôi có thể đưa ra là đặt tất cả các phụ thuộc vào một đối tượng "ngữ cảnh", sau đó được chia sẻ giữa tất cả các phiên bản. Điều này sẽ giảm nhẹ vấn đề hiệu năng.

1

Nếu bạn quan tâm là thử nghiệm chậm, hãy thử chạy song song và không để quá trình thử nghiệm làm gián đoạn lập trình viên của bạn.

Tự động hóa quá trình này:

  • Khi một ai kiểm tra trong, làm cho một xây dựng ra khỏi kho.
  • Chạy thử nghiệm trên bản dựng này.
  • E - Gửi kết quả cho nhà phát triển đã đăng ký.

Sẽ tốt hơn nếu lần đăng ký đầu tiên không được thực hiện cho kho lưu trữ thực. Làm cho nó thành một tạm thời và làm cho việc xây dựng ra khỏi điều này. Tùy chọn, bạn có thể thực hiện các bài kiểm tra hiệu suất, kiểm tra kiểu, v.v. và bao gồm những điều này trong e-mail. Nếu bạn thực hiện việc này, hãy thêm một bước vào quy trình tự động:

  • Nếu kiểm tra vượt qua (và đáp ứng tiêu chí tùy chọn), hãy hợp nhất mã mới với kho thực tế.

Bằng cách này, kiểm tra chậm không quan tâm. Ngoài ra khi một nhà phát triển cần phải biết nếu mã của cô đã phá vỡ một cái gì đó hoặc thực hiện tăng hiệu suất cô mong đợi, cô chỉ cần kiểm tra và chờ đợi cho e - mail tạo ra cho cô ấy.

2

Tôi nghĩ bạn chỉ nên có "DI constructor". Bạn gọi hàm khởi tạo này để thử nghiệm cũng như trong quá trình sản xuất.

class ShortLivedThing { 
    IDependency1 dep1; 
    IDependency1 dep2; 
    IDependency1 dep3; 
    ... 

    int TheRealData; 

    public ShortLivedThing(IDependency1 d1, IDependency2 d2, IDependency3 d3) { 
    dep1 = d1; dep2 = d2; dep3 = d3; 
    } 
} 

Bằng cách này bạn không gặp phải vấn đề khởi tạo cây đối tượng mỗi lần thực hiện cuộc gọi bên ngoài thử nghiệm của bạn. Tất nhiên, đối với sản xuất, bạn phải kết nối chính xác các đối tượng của mình bên ngoài các đối tượng tham gia, đó là một điều tốt.

Tóm lại: không dùng 50% mã hóa DI/50%, đi đến 100% DI.

0

Nếu bạn đang nhắm mục tiêu .NET, hãy xem Autofac. Nó có các phạm vi khác nhau (singleton, factory, container) để tinh chỉnh các khía cạnh sáng tạo, xử lý xác định để sử dụng tài nguyên tại vịnh và cho phép sử dụng các biểu thức GeneratedFactories và lambda để cấu hình các thành phần và tránh chi phí phản chiếu.

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