Refactorización anidada para bucles

Podría encapsular lo que desea hacer con un documento en un controlador. Esto también le permitirá definir nuevos controladores en el futuro que puede pasar al código existente.

interface DocumentHandler {
    void process(Document d);
}

class ExportToPdf implements DocumentHandler { ... }
class AppendToParentPdf implements DocumentHandler { ... }

// Now you're just passing the interface whose implementation does something with the document
void handleDocument(DocumentHandler parentHandler, DocumentHandler childHandler) {
    for(Document parent : documents) {
        parentHandler.process(parent);

        for(Document child : parent.children()) {
            childHandler.process(child);
        }
    }
}

DocumentHandler appendToParent = new AppendToParentPdf();
DocumentHandler exportToPdf = new ExportToPdf();

// pass the child/parent handlers as needed
handleDocument(exportToPdf, appendToParent);
handleDocument(exportToPdf, exportToPdf);

En cuanto a la eficiencia, diría que no intentes optimizar a menos que te encuentres con problemas de rendimiento. En cualquier caso, el problema no será con el bucle anidado sino con la lógica misma que procesa los documentos.

Respuesta 1

¿Hay mejores representaciones de las relaciones entre padres e hijos, como las anteriores, en lugar de forzarme a abrirme paso a través de todos los documentos y sus hijos de manera O (n ^ 2)?

Esto no es O(N^2). Es O(N)donde Nestá el número total de documentos primarios y secundarios. Suponiendo que ningún niño tiene más de un documento padre, no puede mejorar significativamente el rendimiento. Además, el costo del recorrido es probablemente trivial en comparación con el costo de las llamadas que generan los PDF.

El único caso en el que es posible que desee considerar la optimización es si los documentos secundarios pueden ser hijos de varios padres. En ese caso, es posible que desee realizar un seguimiento de los documentos para los que ya ha generado archivos PDF ... y omitirlos si los vuelve a visitar en el recorrido. La prueba para "he visto este documento antes" se puede implementar usando a HashSet.

Respuesta: 2

Para su segunda pregunta, puede usar el patrón de proveedor o una extensión del mismo.

Patrón de proveedor: este patrón tiene sus raíces en el patrón de Estrategia y le permite diseñar sus datos y su comportamiento en una abstracción para que pueda intercambiar la implementación en cualquier momento

Respuesta: 3

Traté de incluir esto en un comentario, pero hay mucho que decir ...

No veo cómo el cambio del que estás hablando es un olor a código. Si los requisitos cambian para esta función simple, entonces cambian. Si solo necesita hacer el cambio en un lugar, entonces parece que ha hecho un buen trabajo. Si su cliente va a necesitar ambas formas de hacerlo (o más), entonces podría considerar algún tipo de patrón de estrategia para no tener que reescribir el código circundante para realizar cualquiera de las funciones.

Si está haciendo docenas de estos cambios por semana, entonces podría ser complicado y probablemente debería hacer un plan sobre cómo lidiar de manera más efectiva con un eje de cambio muy ocupado. De lo contrario, la disciplina y la refactorización pueden ayudarlo a mantenerlo limpio.

En cuanto a si n² es un problema o no, depende. ¿Qué tan grande es n? Si tiene que hacer esto con frecuencia (es decir, docenas de veces por hora) yn está en los miles de ellos, entonces podría tener un problema. De lo contrario, no lo sudaría mientras cumplas o excedas la demanda y tu uso de CPU / disco esté fuera de la zona de peligro.

Respuesta: 4

El problema de la segunda pregunta se puede resolver simplemente creando un inteface Exportermétodo export(Document doc);y luego implementándolo para cada uno de los diversos formatos, por ejemplo class DocExporterImpl implements Exporter.

El primero depende de sus requisitos y ningún patrón de diseño como tal resuelve estos problemas. No puedo ayudarte allí.

Respuesta: 5

Con AWT, ¿cómo importa una imagen en un rectángulo que ha dibujado? Quiero asignar el fondo solo a ese rectángulo en particular.

Tengo una devolución de llamada con instancia de excepción. Actualmente lo manejo de esta manera, pero creo que hay una mejor manera. Me gustaría escuchar algún comentario de un experto en Java. =) ... onError (Excepción e) {...

Todo me parece correcto: obtener un objeto de resultados, obtener una matriz de series, obtener un objeto en el índice y obtener una matriz de datos. privado void downloadAllData () lanza JSONException {queryApi (); JSONObject ...

Tengo una clase genérica con parámetro que extiende Paint. Realmente no entiendo por qué debería lanzarlo manualmente a T en el primer constructor. ¿Qué estoy haciendo mal? O este es el caso cuando el ...