En nuestra aplicación Delphi 2007 estamos usando muchas de las siguientes construcciones
FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData));
FindOwnerClass recorre la jerarquía de Propietario del componente actual hacia arriba para encontrar una clase específica (en el ejemplo TdmBasicData). El objeto resultante se almacena en la variable de campo FdmBasic. Usamos esto principalmente para pasar módulos de datos.
Ejemplo: al generar un informe, los datos resultantes se comprimen y almacenan en un campo Blob de una tabla a la que se accede a través de un módulo de datos TdmReportBaseData. En un módulo separado de nuestra aplicación, hay una funcionalidad para mostrar los datos del informe en un formulario Paged usando ReportBuilder. El código principal de este módulo (TdmRBReport) utiliza una clase TRBTempdatabase para convertir los datos de blobs comprimidos en diferentes tablas que pueden utilizarse en el diseñador de informes de tiempo de ejecución de Reportbuilder. TdmRBReport tiene acceso a TdmReportBaseData para todo tipo de datos relacionados con el informe (tipo de informe, configuración de cálculo de informes, etc.). TRBTempDatabase está construido en TdmRBReport pero tiene que tener acceso a TdmReportBasedata. Entonces esto se hace usando la construcción anterior:
constructor TRBTempDatabase.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData;
end;{- .Create }
Mi sensación es que esto significa que TRBTempDatabase conoce mucho a su propietario, y me preguntaba si esto es algún tipo de olor a código o Anti-patrón.
¿Qué piensas sobre esto? ¿Es este un olor a código? Si es así, ¿cuál es una mejor manera?
fuente
Respuestas:
Este tipo de patrón se parece a un patrón de localización de servicios que fue descrito por primera vez por Martin Fowler (que se identificó como un antipatrón común).
La inyección de dependencia basada en la construcción es preferible a un localizador de servicios, ya que promueve la visibilidad de los parámetros requeridos y promueve pruebas unitarias más simples.
También más notablemente también viola la Ley de Demeter
La mejor manera
Efectivamente, la mejor manera es eliminar la llamada del localizador de servicios dentro de la clase y pasar el propietario correcto como parámetro dentro de su constructor. Incluso si esto significa que tiene una clase de servicio que realiza una búsqueda del propietario y luego la pasa al constructor de la clase
fuente
As a simple example, when one wants to walk a dog, it would be folly to command the dog's legs to walk directly; instead one commands the dog and lets it take care of its own legs.
Una de las dificultades para que los objetos secundarios sepan demasiado sobre los padres es que terminas implementando patrones que pueden (y con frecuencia lo hacen) acoplarse demasiado, lo que crea grandes dolores de cabeza de dependencia y a menudo se vuelve muy difícil de modificar y mantener de manera segura mas tarde.
Dependiendo de cuán profundamente estén conectadas sus dos clases, parece un poco como la descripción de Fowler de la Envidia de características o los olores inapropiados del código de intimidad son evidentes.
Parece que es necesario cargar o leer una clase con datos, en cuyo caso podría usar una serie de patrones alternativos para romper la dependencia entre el niño y su cadena de padres, y parece que necesita delegar la tarea de acceder su clase de datos en lugar de hacer que la clase de acceso a datos sea responsable de hacer todo por sí mismo.
fuente