Pregunta

Tengo un objeto denominado Parámetros que consigue sacudidos de un método a abajo y arriba el árbol de llamadas, a través de los límites del paquete. Tiene unos cincuenta variables de estado. Cada método puede utilizar una o dos variables para controlar su salida.

creo que esto es una mala idea, por culpa No puedo ver fácilmente lo que necesita un método para la función, o incluso lo que podría suceder si con una determinada combinación de parámetros para el módulo de Y, que es totalmente ajeno a mi módulo actual.

¿Cuáles son algunas buenas técnicas para disminuir el acoplamiento a este objeto dios, o idealmente eliminarlo?

        public void ExporterExcelParFonds(ParametresExecution parametres)
    {
        ApplicationExcel appExcel = null;
        LogTool.Instance.ExceptionSoulevee = false;


        bool inclureReferences = parametres.inclureReferences;
        bool inclureBornes = parametres.inclureBornes;
        DateTime dateDebut = parametres.date;
        DateTime dateFin = parametres.dateFin;

        try
        {
            LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference);

            bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds);
            if (!fichiersPreparesAvecSucces)
            {
                parametres.afficherRapportApresGeneration = false;
                LogTool.Instance.ExceptionSoulevee = true;
            }
            else
            {

La persona que llama haría:

                PortefeuillesReference pr = new PortefeuillesReference();
            pr.ExporterExcelParFonds(parametres);
¿Fue útil?

Solución

En primer lugar, con el riesgo de afirmar lo obvio:. Pasar los parámetros que son utilizados por los métodos, en lugar del objeto dios

Sin embargo, esto podría conducir a algunos métodos que requieren enormes cantidades de parámetros, ya que ellos llaman otros métodos, que se llaman a otros métodos, a su vez, etcétera. Esa fue probablemente la inspiración para poner todo en un objeto de dios. Voy a dar un ejemplo simplificado de un método de este tipo con demasiados parámetros; que tendrá que imaginar que "demasiados" == 3 aquí :-)

public void PrintFilteredReport(
   Data data, FilterCriteria criteria, ReportFormat format)
{
   var filteredData = Filter(data, criteria);
   PrintReport(filteredData, format);
}

Así que la pregunta es, ¿Cómo podemos reducir la cantidad de parámetros sin tener que recurrir a un objeto de dios? La respuesta es deshacerse de la programación de procedimiento y hacer buen uso del diseño orientado a objetos. Los objetos se pueden utilizar entre sí sin necesidad de conocer los parámetros que se utilizan para inicializar sus colaboradores:

// dataFilter service object only needs to know the criteria
var dataFilter = new DataFilter(criteria);

// report printer service object only needs to know the format
var reportPrinter = new ReportPrinter(format);

// filteredReportPrinter service object is initialized with a
// dataFilter and a reportPrinter service, but it doesn't need
// to know which parameters those are using to do their job
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter);

Ahora el método FilteredReportPrinter.Print se puede implementar con un solo parámetro:

public void Print(data)
{
   var filteredData = this.dataFilter.Filter(data);
   this.reportPrinter.Print(filteredData);
}

A propósito, este tipo de separación de las preocupaciones y la inyección de dependencia es bueno para más de parámetros simplemente eliminando. Si tiene acceso a los objetos de colaboradores a través de interfaces, entonces eso hace que su clase

  • muy flexible: puede configurar FilteredReportPrinter con cualquier aplicación de filtro / impresora se puede imaginar
  • muy comprobable: se puede pasar en colaboradores simulacros con respuestas enlatadas y verificar que se utilizaron correctamente en una prueba de unidad

Otros consejos

Si todos los métodos están utilizando la misma clase Parameters entonces tal vez debería ser una variable miembro de una clase con los métodos pertinentes en él, entonces usted puede pasar Parameters en el constructor de esta clase, asignarlo a una variable miembro y todas sus métodos pueden utilizarlo con tener que pasar como un parámetro.

Una buena manera de empezar refactorización esta clase dios es mediante su división en partes más pequeñas. Encontrar grupos de propiedades que están relacionadas y romper hacia fuera en su propia clase.

A continuación, puede volver a los métodos que dependen de Parameters y ver si se puede reemplazar con una de las clases más pequeñas que ha creado.

Es difícil dar una solución buena y sin algunos ejemplos de código y situaciones del mundo real.

Parece que no está solicitando principios orientados a objetos (OO) en su diseño. Dado que se menciona la palabra "objeto" Supongo que está trabajando dentro de una especie de paradigma orientado a objetos. Recomiendo a convertir su "árbol de llamadas" en objetos que modelan el problema que se está resolviendo. Un "objeto dios" es definitivamente algo a evitar. Creo que es posible que se echa en falta algo fundamental ... Si después de algunos ejemplos de código que puede ser capaz de responder con más detalle.

Consulta cada cliente por sus parámetros necesarios e inyectarlos?

Ejemplo: cada "objeto" que requiere "parámetros" es un "Cliente". Cada "Cliente" expone una interfaz a través del cual un "Agente de configuración" consulta el cliente para sus parámetros requeridos. El Agente de configuración, luego "inyecta" los parámetros (y sólo los requeridos por un cliente).

Para los parámetros que el comportamiento dictado, se puede crear una instancia de un objeto que presenta el comportamiento configurado. Entonces clases de cliente sólo tiene que utilizar la instancia de objeto - ni el cliente ni el servicio tienen que saber cuál es el valor del parámetro es. Por ejemplo, para un parámetro que indica dónde puede leer datos de, tener la FlatFileReader, XMLFileReader y DatabaseReader todos heredan la misma clase base (o implementar la misma interfaz). uno de ellos instantiate como base el valor del parámetro, los clientes de la clase lector acaba de pedir datos al objeto instanciado lector sin saber si los datos provienen de un archivo o de la BD.

Para empezar se puede romper su gran clase ParametresExecution en varias clases, una por cada paquete, que sólo contienen los parámetros para el paquete.

Otra dirección podría ser la de pasar el objeto ParametresExecution en el momento de la construcción. Usted no tendrá que pasar en torno a cada llamada a la función.

(estoy asumiendo que esto está dentro de un entorno Java o .NET) convertir la clase en un producto único. Añadir un método estático llamado "getInstance ()" o algo similar a llamar para obtener el paquete nombre-valor (y parada "andar" alrededor - véase capítulo 10 de "código completo" libro.)

.

Ahora la parte difícil. Presumiblemente, esto está dentro de una aplicación de web o algún otro medio no lote / single-hilo. Por lo tanto, para obtener acceso a la instancia correcta cuando el objeto no es realmente un verdadero producto único, que tiene que esconderse dentro de la lógica de selección del descriptor de acceso estático.

En Java, se puede establecer una referencia "secuencia de procesamiento local", e inicializar cuando cada solicitud o sub-tarea se inicia. A continuación, el código de descriptor de acceso en términos de ese local de subprocesos. No sé si existe algo análogo en .NET, pero siempre se puede fingir con un diccionario (Hash, mapa), que utiliza la instancia hilo actual como clave.

Es un comienzo ... (siempre hay descomposición de la misma nota, pero me construyó un marco que tiene un valor muy similar tienda semi-global dentro de ella)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top