2009-02-20 17 views
9

Estoy escribiendo un programa de análisis de tamaño medio (5-10kloc) en MATLAB (no es mi decisión), y estoy tratando de usar la inyección de dependencia para hacer que mi código sea más comprobable. Creo que entiendo el modelo básico de inyección de objeto/constructor, pero estoy confundido sobre cómo se escala el gráfico de dependencia.Inyección de dependencia sin marco

Por ejemplo, si tengo el objeto A, que tiene un objeto B, que tiene un objeto C, y el objeto C tiene una dependencia que necesita ser inyectada, ¿necesito pasarlo a través de toda la cadena? Eventualmente, dado que este es un programa de análisis de datos, básicamente todo vuelve a un objeto/método de AnalyzeData, ¿significa esto que ese objeto tiene que tener inyectadas todas las dependencias de todo el programa?

Quizás la respuesta sea simplemente utilizar ServiceFactory/ServiceProvider en este caso, pero me gustaría saber si es posible escalar muchas dependencias hasta un gran gráfico de objetos sin un marco.

Además, se fomentan las correcciones en mi pensamiento/redacción/fundamentos: básicamente he aprendido la mayor parte de esto a través de Google/HN/SO.

+0

¿Qué significa HN? – iddober

+0

Esto no es de ninguna manera una respuesta, pero de todos los que podrían terminar en esta pregunta, eche un vistazo al (bastante agradable) marco [DI DI para Matlab] (https://github.com/mattmcd/mdepin), escrito por Matt McDonnell. Esto debería ponerlo en marcha ... – Kris

+0

Sigue el comentario de Kris, aquí hay un blog sobre el tema que está dirigido a MATLAB (y que usa el marco DI de Matt MCDonnell): http://blogs.mathworks.com/developer/2016/02/24/dependency-injection/ –

Respuesta

2

Haga rodar su propio contenedor IoC donde puede solicitar sus dependencias sin necesidad de inyectarlos, o use el patrón de puerta de enlace estática para obtener un singleton para crear clases dinámicamente usando una fábrica.

me encontré con este video una introducción muy útil a estos temas - http://www.dnrtv.com/default.aspx?showNum=126

2

Si lo hace la inyección de dependencia con la mano es mejor que no pasa a través de dependencias. Simplemente crea C con su dependencia, crea B con C, crea A con B. No es necesario que A sepa algo sobre C o su dependencia. Simplemente conoce la interfaz de B y, por lo general, las dependencias no son parte de la interfaz de un objeto. respuesta

5

Matlab-agnóstico:

Si (A necesita B) y (B necesita C), entonces primero se crea C, a continuación, crear B y C pasan a B. A continuación, se crea una y aprobar (B tiene C) a A.

Ahora, si C necesita una dependencia para ser inyectada, llámala D, aún puedes hacer esto después de esta secuencia de eventos usando la inyección setter. Este sería el caso si la dependencia es opcional para C. De lo contrario, es probable que una falla en el inicio del programa que C no se inyectó con D antes se pasó a B.

Si desea utilizar el constructor inyectable para inyectar D en C después de que ya lo haya hecho (A tiene (B tiene C)), entonces tendrá que usar la inyección setter para pasar una nueva (C tiene D) a B, pero esta secuencia de eventos generalmente no es una escenario válido para DI.

0

No sé nada de Matlab, pero supongo (según sus palabras) que hay objetos. Si es así, busque Service Locator en lugar de Dependency Injection. Los localizadores de servicios son muy simples de implementar, por lo que no requieren marcos.

+0

Service locator (anti) pattern está ampliamente obsoleto. Crea un enorme alcance global y no tiene visibilidad sobre dónde se usan los objetos. – time4tea

2

responsabilidad: lenguaje orientado a objetos respuesta agnóstica

No, no es necesario pasar a través de las dependencias gráfico de objetos conjunto. No tener que instanciar tipos concretos o pasarlos como parámetros es el objetivo de DI. En general, tendrá alguna otra entidad, llamada Assembler por ejemplo, que inyectará estas dependencias. El ensamblador puede ser ad-hock, escrito a mano o puede ser un poco de marco DI.

Por ejemplo:

  • Clase CLSA tiene una propiedad de tipo IB interfaz.
  • La clase ClsB implementa IB y tiene una propiedad de tipo interfaz IC.
  • Class ClsC implementa IC.

Su ensambladora de arrancar la aplicación y:

  1. crear instancia con nombre o C de la clase CLSC
  2. crear instancia con nombre OB de CLSB e inyectarlo con oC
  3. crear instancia con nombre oA e inyectarlo con oB

Todo su dominio o los proyectos solo conocen interfaces. El ensamblador conoce todo el objeto, pero su propósito es simplemente crear un gráfico de objetos y poner todo en movimiento. El ensamblador escrito a mano es perfectamente apropiado; algunas personas prefieren escribir código de cableado que usar archivos de configuración. No piense que vale la pena el problema de escribir assembler (DI framework) si no planea usarlo más de una vez. El punto es que tus clases están escritas en DI moda.

Tome un vistazo a este artículo: http://books.google.com/books?id=vRxAnRb3mb4C&pg=PP1&dq=Danijel+Arsenovski#PPA428,M1

2

Si entiendo bien su pregunta, la respuesta puede depender de la forma en que está creando las clases de las que se ejemplariza los objetos. Dentro de las versiones más nuevas de MATLAB, las clases se pueden definir de dos maneras: una clase "valor" o una clase "manejar" (documentación de MATLAB here). Citando de la documentación:

  • clase Valor:. "Objetos de clases de valores están asociados permanentemente con las variables a las que se asignan cuando se copia un objeto de valor, los datos del objeto también se copian y el nuevo el objeto es independiente de los cambios en el objeto original. Las instancias se comportan como las clases estándar numer y struct de MATLAB ".

  • manija clase:.. "objetos de clases mango utilizan un mango para hacer referencia a objetos de la clase A mango es una variable que identifica una instancia particular de una clase Cuando se copia un objeto de mango, el mango se copia , pero no los datos almacenados en las propiedades del objeto. La copia se refiere a los mismos datos que el original: si cambia el valor de una propiedad en el objeto original, el objeto copiado refleja el mismo cambio."

El código de ejemplo siguiente muestra algunos ejemplos de cómo interactuar con los 'objetos anidados' al igual que se ha descrito anteriormente, tanto para los objetos anidados de clase de valor y manejar la clase anidada objetos:

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

Como se puede ver, el uso de una clase mango puede ayudar a evitar tener que las llamadas a funciones de cadena y referencias de campo mediante el almacenamiento de una copia de la empuñadura (esencialmente un puntero) en otra variable. Manejar clases también tak e la necesidad de sobrescribir las copias antiguas de los objetos con los nuevos devueltos por los métodos que operan en esos objetos.

Espero que esto ayude con lo que estabas preguntando.

Cuestiones relacionadas