2009-02-20 30 views
9

Tôi đang viết một chương trình phân tích cỡ trung bình (5-10kloc) trong MATLAB (không phải quyết định của tôi), và tôi đang cố gắng sử dụng tiêm phụ thuộc để làm cho mã của tôi dễ kiểm tra hơn. Tôi nghĩ rằng tôi hiểu mô hình tiêm đối tượng/constructor cơ bản, nhưng tôi bị nhầm lẫn về cách điều này làm tăng biểu đồ phụ thuộc. Ví dụ, nếu tôi có đối tượng A, có đối tượng B, có đối tượng C và đối tượng C có phụ thuộc cần được tiêm, tôi có cần truyền nó qua toàn bộ chuỗi không? Không. Cuối cùng, vì đây là một chương trình phân tích dữ liệu, mọi thứ về cơ bản trở lại một đối tượng/phương pháp AnalyzeData, điều này có nghĩa là đối tượng đó phải có tất cả các phụ thuộc của toàn bộ chương trình được tiêm không?Sự tiêm phụ thuộc không có khuôn khổ

Có lẽ câu trả lời chỉ đơn giản là sử dụng ServiceFactory/ServiceProvider trong trường hợp này, nhưng tôi muốn biết liệu có thể mở rộng nhiều phụ thuộc đến một đồ thị đối tượng lớn không có khung.

Ngoài ra, các chỉnh sửa về tư duy/từ ngữ/nguyên tắc cơ bản của tôi được khuyến khích - Tôi đã học về cơ bản phần lớn thông qua Google/HN/SO.

+0

HN là gì? – iddober

+0

Đây không phải là câu trả lời mà là của tất cả những người có thể kết thúc tại câu hỏi này, có một cái nhìn tại (khá tốt đẹp) [DI framework for Matlab] (https://github.com/mattmcd/mdepin), viết bởi Matt McDonnell. Điều này sẽ giúp bạn đi .... – Kris

+0

Theo dõi nhận xét của Kris, đây là một blog về chủ đề phục vụ cho MATLAB (và sử dụng khuôn khổ DI của Matt MCDonnell): http://blogs.mathworks.com/developer/2016/02/24/tiêm phụ thuộc/ –

Trả lời

2

Cuộn vùng chứa IoC của riêng bạn, nơi bạn chỉ có thể yêu cầu các phụ thuộc của mình mà không cần phải tiêm chúng hoặc sử dụng mẫu cổng tĩnh để tạo một singleton để tạo các lớp động bằng cách sử dụng một nhà máy.

Tôi tìm thấy video này giới thiệu thực sự hữu ích cho các chủ đề này - http://www.dnrtv.com/default.aspx?showNum=126

2

Nếu bạn làm dependency injection bằng tay bạn nên không đi qua phụ thuộc qua. Bạn chỉ cần tạo C với sự phụ thuộc của nó, tạo B với C, tạo A với B. Không cần A để biết bất cứ điều gì về C hoặc sự phụ thuộc của nó. Nó chỉ biết về giao diện của B và thường phụ thuộc không phải là một phần của giao diện cho một đối tượng. câu trả lời

5

Matlab-agnostic:

Nếu (A cần B) và (B cần C) thì trước tiên bạn tạo C, sau đó tạo ra B và vượt qua C đến B. Sau đó, bạn tạo A và vượt qua (B có C) đến A.

Bây giờ, nếu C cần một phụ thuộc để được tiêm, gọi nó là D, bạn vẫn có thể làm điều này sau chuỗi sự kiện này bằng cách sử dụng tiêm setter. Điều này sẽ là trường hợp nếu phụ thuộc là tùy chọn cho C. Nếu không nó có khả năng là một lỗ hổng trong khởi tạo chương trình của bạn mà C không được tiêm với D trước khi nó được chuyển đến B.

Nếu bạn muốn sử dụng hàm tạo tiêm cho tiêm D vào C sau khi bạn đã có (A có (B có C)), sau đó bạn sẽ phải sử dụng tiêm setter cho đi qua một mới (C có D) đến B, nhưng chuỗi sự kiện này thường không phải là một kịch bản hợp lệ cho DI.

0

Không biết gì về Matlab, nhưng tôi giả định (từ lời nói của bạn) rằng có các đối tượng. Nếu có, hãy tìm một số Service Locator thay vì Dependency Injection. Dịch vụ Định vị rất đơn giản để thực hiện, do đó, không có khung yêu cầu.

+0

Mẫu định vị dịch vụ (chống) được sử dụng rộng rãi. Nó tạo ra một phạm vi toàn cầu khổng lồ, và không có khả năng hiển thị về nơi các đối tượng của bạn được sử dụng. – time4tea

2

Disclaimer: ngôn ngữ OO thuyết bất khả tri câu trả lời

Không, bạn không cần phải vượt qua phụ thuộc thông qua đồ thị toàn bộ đối tượng. Không phải khởi tạo các loại bê tông hoặc truyền chúng như các tham số là điểm của DI. Nói chung, bạn sẽ có một số thực thể khác, được gọi là Assembler chẳng hạn, sẽ tiêm những phụ thuộc này. Assembler có thể được quảng cáo-hock, viết tay hoặc có thể là một số DI framework.

Ví dụ:

  • Lớp CLSA có một loại tài sản của giao diện IB.
  • Class ClsB thực hiện IB và có thuộc tính loại giao diện IC.
  • Class ClsC thực hiện IC.

Assembler của bạn sẽ bootstrap ứng dụng và:

  1. tạo ví dụ đặt tên oC của lớp CLSC
  2. tạo ví dụ đặt tên OB của ClsB và tiêm nó với oC
  3. tạo ví dụ đặt tên oa và tiêm nó với oB

Tất cả tên miền của bạn o bjects chỉ biết giao diện. Assembler biết tất cả các đối tượng, nhưng mục đích của nó chỉ là tạo đồ thị đối tượng và đặt mọi thứ trong chuyển động. Trình biên tập viết tay là hoàn toàn phù hợp; một số người thích viết mã dây hơn là sử dụng các tập tin cấu hình. Đừng nghĩ rằng nó là giá trị khó khăn bằng văn bản lắp ráp (DI framework) nếu bạn không có kế hoạch sử dụng nó nhiều hơn một lần. Vấn đề là các lớp học của bạn được viết bằng thời trang DI.

Hãy xem bài viết này: http://books.google.com/books?id=vRxAnRb3mb4C&pg=PP1&dq=Danijel+Arsenovski#PPA428,M1

2

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, câu trả lời có thể phụ thuộc vào cách bạn đang tạo các lớp học mà từ đó bạn nhanh chóng các đối tượng. Trong các phiên bản mới nhất của MATLAB, các lớp có thể được định nghĩa theo hai cách: một lớp "giá trị" hoặc một lớp "xử lý" (tài liệu MATLAB here). Trích dẫn từ tài liệu:

  • lớp Giá trị:. "Đối tượng của lớp học giá trị có liên quan đến vĩnh viễn với các biến mà họ được giao nhiệm vụ Khi một đối tượng giá trị được sao chép, dữ liệu của đối tượng cũng sao chép và mới đối tượng là độc lập với các thay đổi đối với đối tượng ban đầu. Các thể hiện hoạt động giống như các lớp số và cấu trúc MATLAB chuẩn. "

  • Xử lý lớp: "Các đối tượng của các lớp xử lý sử dụng một tay cầm để tham chiếu các đối tượng của lớp. Khi một đối tượng xử lý được sao chép, xử lý sẽ được sao chép , nhưng không phải là dữ liệu được lưu trữ trong thuộc tính của đối tượng Bản sao đề cập đến cùng một dữ liệu như bản gốc — nếu bạn thay đổi giá trị thuộc tính trên đối tượng gốc, đối tượng được sao chép phản ánh cùng một thay đổi."

Mẫu mã dưới đây đưa ra một số ví dụ về làm thế nào để tương tác với '' đối tượng lồng nhau như bạn mô tả ở trên, cả hai đối tượng lồng nhau giá trị hạng nhất và xử lý đẳng cấp lồng đối tượng:

% For value classes: 

objC = C(...); % Make an object of class C, where "..." stands 
       % for any input arguments 
objB = B(...,objC); % Make an object of class B, passing it objC 
        % and placing objC in field 'objC' 
objA = A(...,objB); % Make an object of class A, passing it objB 
        % and placing objB in field 'objB' 

% If the '.' operator (field access) is defined for the objects: 

objA.objB.objC.D = 1; % Set field 'D' in objC to 1 
objA.objB.objC = foo(objA.objB.objC,...); % Apply a method that 
              % modifies objC and 
              % returns the new 
              % object 

% For handle classes: 

hC = C(...); % Get a handle (reference) for a new object of class C 
hB = B(...,hC); % Get a handle for a new object of class B, 
       % passing it handle hC and placing it in field 'hC' 
hA = A(...,hB); % Get a handle for a new object of class A, 
       % passing it handle hB and placing it in field 'hB' 

% If the '.' operator (field access) is defined for the objects: 

hC.D = 1; % Set field 'D' to 1 for object referenced by hC; Note 
      % that hC and hA.hB.hC both point to same object, and 
      % can thus be used interchangably 
foo(hC); % Apply a method that modifies the object referenced by hC 

% If instead using get/set methods for the handle object: 

set(hC,'D',1); 
set(get(get(hA,'hB'),'hC'),'D',1); % If variable hC wasn't made, get 
            % reference from nested objects 
foo(hC); 
foo(get(get(hA,'hB'),'hC')); 

Như bạn có thể thấy, sử dụng lớp xử lý có thể giúp bạn tránh phải thực hiện các cuộc gọi chức năng và tham chiếu trường bằng cách lưu bản sao tay cầm (về cơ bản là con trỏ) trong biến khác. e đi sự cần thiết phải ghi đè lên các bản sao cũ của các đối tượng với những cái mới được trả về bởi các phương thức hoạt động trên các đối tượng đó.

Hy vọng điều này sẽ giúp với những gì bạn đang yêu cầu.

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