2009-02-20 32 views
9

Sto scrivendo un programma di analisi di medie dimensioni (5-10kloc) in MATLAB (non è una mia decisione), e sto cercando di utilizzare l'integrazione delle dipendenze per rendere il mio codice più testabile. Penso di capire il modello base di iniettore oggetto/costruttore, ma sono confuso su come questo riduca in scala il grafico delle dipendenze.Iniezione di dipendenza senza framework

Per esempio, se ho l'oggetto A, che ha-un oggetto B, che ha-un oggetto C e l'oggetto C ha una dipendenza che deve essere iniettata, devo passare attraverso l'intera catena? Alla fine, poiché si tratta di un programma di analisi dei dati, tutto torna fondamentalmente a un oggetto/metodo AnalyzeData, significa che quell'oggetto deve avere tutte le dipendenze dell'intero programma iniettato?

Forse la risposta è semplicemente utilizzare ServiceFactory/ServiceProvider in questo caso, ma mi piacerebbe sapere se è possibile ridimensionare molte dipendenze fino a un grande oggetto grafico senza un framework.

Inoltre, le correzioni sul mio modo di pensare/parole/principi fondamentali sono incoraggiate - fondamentalmente ho imparato la maggior parte di questo tramite Google/HN/SO.

+0

Che cosa significa HN? – iddober

+0

Questa non è affatto una risposta, ma di tutti coloro che potrebbero finire a questa domanda, dare un'occhiata al (piuttosto bello) [DI framework per Matlab] (https://github.com/mattmcd/mdepin), scritto di Matt McDonnell. Questo dovrebbe farti andare .... – Kris

+0

Segui il commento di Kris, ecco un blog sull'argomento dedicato a MATLAB (e usando il framework DI di Matt MCDonnell): http://blogs.mathworks.com/developer/2016/02/24/dipendenza dall'iniezione/ –

risposta

2

Rolla il tuo contenitore IoC dove puoi semplicemente chiedere le tue dipendenze senza doverle iniettare, o usare il modello di gateway statico per ottenere un singleton per creare classi dinamicamente usando una fabbrica.

ho trovato questo video un intro molto utile per questi argomenti - http://www.dnrtv.com/default.aspx?showNum=126

2

Se fai dipendenza iniezione a mano è meglio che non passa attraverso le dipendenze. Crei semplicemente C con la sua dipendenza, crei B con C, crei A con B. Non c'è bisogno che A sappia qualcosa su C o sulla sua dipendenza. Conosce solo l'interfaccia di B e solitamente le dipendenze non fanno parte dell'interfaccia per un oggetto. risposta

5

Matlab-agnostic:

Se (A ha bisogno di B) e (B ha bisogno di C), allora è necessario creare prima C, quindi creare B e passare C a B. Quindi si crea una e superare (B ha C) a

Ora, se C ha bisogno di una dipendenza da iniettare, chiamatelo D, è ancora possibile farlo dopo questa sequenza di eventi utilizzando l'iniezione setter. Questo sarebbe il caso se la dipendenza è facoltativo per C. In caso contrario, è probabile che un difetto nel vostro programma che l'inizializzazione C non è stato iniettato con D prima è stato passato a B.

Se si desidera utilizzare il costruttore iniezione per iniettare D in C dopo che hai già fatto (A ha (B ha C)), allora dovrai usare l'iniezione setter per passare un nuovo (C ha D) a B, ma questa sequenza di eventi di solito non è un scenario valido per DI.

0

Non so nulla di Matlab, ma presumo (dalle tue parole) che ci siano oggetti. In tal caso, rivolgersi a Service Locator anziché a Dependency Injection. I Service Locator sono molto semplici da implementare, quindi non sono necessari framework.

+0

La localizzazione (anti) del localizzatore di servizio è ampiamente deprecata. Crea un enorme ambito globale e nessuna visibilità su dove vengono utilizzati i tuoi oggetti. – time4tea

2

Esonero di responsabilità: il linguaggio OO risposta agnostica

No, non è necessario passare attraverso le dipendenze intero oggetto grafico. Non dover istanziare tipi concreti o passarli come parametri è il punto di DI. In generale, avrai qualche altra entità, chiamata ad esempio Assembler, che inietterà queste dipendenze. L'assemblatore può essere ad-hock, scritto a mano o può essere un framework DI.

Ad esempio:

  • Classe CLSA ha una proprietà di tipo di interfaccia IB.
  • Classe ClsB implementa IB e ha una proprietà di tipo IC interfaccia .
  • Utensili classe ClsC IC.

vostro assemblatore sarà bootstrap l'applicazione e:

  1. creare un'istanza denominata oC di classe CLSC
  2. creare un'istanza denominata oB di CLSB e iniettare con oC
  3. creare un'istanza denominata oA e iniettarlo con oB

Tutto il dominio o bjects conosce solo le interfacce. Assembler conosce tutto l'oggetto, ma il suo scopo è solo quello di creare un oggetto grafico e mettere tutto in movimento. Assembler scritto a mano è perfettamente appropriato; alcuni preferiscono scrivere codice di cablaggio piuttosto che usare i file di configurazione. Non pensate che valga la pena di scrivere assembler (DI framework) se non pensate di usarlo più di una volta. Il punto è che le tue lezioni sono scritte in DI fashion.

Date un'occhiata a questo articolo: http://books.google.com/books?id=vRxAnRb3mb4C&pg=PP1&dq=Danijel+Arsenovski#PPA428,M1

2

Se ho capito bene la tua domanda, la risposta può dipendere da come si sta creando le classi da cui si crea un'istanza gli oggetti. All'interno delle versioni più recenti di MATLAB, le classi possono essere definite in due modi: una classe "valore" o una classe "handle" (documentazione MATLAB here). Citando dalla documentazione:

  • classe di valore:. "Oggetti di classi di valore sono permanentemente connessi con le variabili a cui sono assegnati Quando un oggetto valore viene copiato, i dati dell'oggetto viene copiato anche e il nuovo l'oggetto è indipendente dalle modifiche all'oggetto originale. Le istanze si comportano come classi standard numeriche e struct MATLAB. "

  • maniglia classe:.. "Oggetti di classi maniglia utilizzare una maniglia per fare riferimento oggetti della classe A maniglia è una variabile che identifica una particolare istanza di una classe Quando un oggetto maniglia viene copiato, la maniglia viene copiato ma non i dati memorizzati nelle proprietà dell'oggetto. La copia fa riferimento agli stessi dati dell'originale: se si modifica un valore di una proprietà sull'oggetto originale, l'oggetto copiato riflette la stessa modifica."

Il codice di esempio che segue fornisce alcuni esempi di come interagire con 'oggetti nidificati' come hai descritto sopra, sia per gli oggetti nidificati valore-classe e gestire classi nidificate oggetti:

% 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')); 

Come si può vedere, utilizzando una classe maniglia può aiutare a evitare di dover chiamate di funzione chain e riferimenti di campo memorizzando una copia del manico (essenzialmente un puntatore) in un'altra variabile. maniglia classi anche tak E via la necessità di sovrascrivere le vecchie copie degli oggetti con quelle nuove restituite dai metodi che operano su quegli oggetti.

Spero che questo aiuti con quello che stavi chiedendo.