2
\$\begingroup\$

I have this code to generate some tables in my PDF document for my Android app. It works fine, but I just think I need to refactor it as the same structure is repeated 3 times.

//tables!
  public static PdfPTable createTableA() {

      //empty space
        Paragraph paragraph = new Paragraph();
        addEmptyLine(paragraph, 3);

        int numberOfCells = 0;
        int numberOfIdealCells = 0;

        //int
        numberOfCells = Checks.aResults.size();
        numberOfIdealCells = numberOfCells;  


          Log.d("mensa", "numero de preguntas : "+numberOfCells);


          //TODO REFACTOR THIS LOGIC TO KNOW IF NUMBER OF CELLS OK!

          if (numberOfCells %3 != 0) {
              Log.d("mensa", "no lo es");
              numberOfIdealCells +=1;

              if (numberOfIdealCells %3 != 0) {
                  numberOfIdealCells +=1;

            }

        }

          Log.d("mensa", "sikas");
          Log.d("mensa", "numero de preguntas afters: "+numberOfIdealCells);

            // a table with three columns
            PdfPTable table = new PdfPTable(3);

            Checks.aResults.keySet().iterator();

              Iterator<String> iteratorSectionC = Checks.aResults.keySet().iterator();
            while(iteratorSectionC.hasNext()) {

                String key=(String)iteratorSectionC.next();

                int value=(int)Checks.aResults.get(key);

               // Log.d("mensa", "mi Pregunta iteratorSectionC::\n"+key+" valor::"+value);

                //Paragraph pN = new Paragraph(key+" val::"+value);
                //document.add(pN);
                table.addCell(key+" val::"+value);

            }

            //add empty cells

            int difference = numberOfIdealCells - numberOfCells;

            if (difference > 0) {

                for(int i = 0; i<difference ; i++){
                    table.addCell("");

                }
            }



            return table;
        }

  public static PdfPTable createTableB() {

      //empty space
        Paragraph paragraph = new Paragraph();
        addEmptyLine(paragraph, 3);

        int numberOfCells = 0;
        int numberOfIdealCells = 0;

        //int
        numberOfCells = Checks.bResults.size();
        numberOfIdealCells = numberOfCells;  


          Log.d("mensa", "numero de preguntas : "+numberOfCells);


          //TODO REFACTOR THIS LOGIC TO KNOW IF NUMBER OF CELLS OK!

          if (numberOfCells %3 != 0) {
              Log.d("mensa", "no lo es");
              numberOfIdealCells +=1;

              if (numberOfIdealCells %3 != 0) {
                  numberOfIdealCells +=1;

            }

        }

          Log.d("mensa", "sikas");
          Log.d("mensa", "numero de preguntas afters: "+numberOfIdealCells);

            // a table with three columns
            PdfPTable table = new PdfPTable(3);

            Checks.bResults.keySet().iterator();

              Iterator<String> iteratorSectionC = Checks.bResults.keySet().iterator();
            while(iteratorSectionC.hasNext()) {

                String key=(String)iteratorSectionC.next();

                int value=(int)Checks.bResults.get(key);

               // Log.d("mensa", "mi Pregunta iteratorSectionC::\n"+key+" valor::"+value);

                //Paragraph pN = new Paragraph(key+" val::"+value);
                //document.add(pN);
                table.addCell(key+" val::"+value);

            }

            //add empty cells

            int difference = numberOfIdealCells - numberOfCells;

            if (difference > 0) {

                for(int i = 0; i<difference ; i++){
                    table.addCell("");

                }
            }



            return table;
        }

  public static PdfPTable createTableC() {

      //empty space
        Paragraph paragraph = new Paragraph();
        addEmptyLine(paragraph, 3);  

    int numberOfCells = 0;
    int numberOfIdealCells = 0;

    //int
    numberOfCells = Checks.cResults.size();
    numberOfIdealCells = numberOfCells;  


      Log.d("mensa", "numero de preguntas : "+numberOfCells);


      //TODO REFACTOR THIS LOGIC TO KNOW IF NUMBER OF CELLS OK!

      if (numberOfCells %3 != 0) {
          Log.d("mensa", "no lo es");
          numberOfIdealCells +=1;

          if (numberOfIdealCells %3 != 0) {
              numberOfIdealCells +=1;

        }

    }

      Log.d("mensa", "sikas");
      Log.d("mensa", "numero de preguntas afters: "+numberOfIdealCells);

        // a table with three columns
        PdfPTable table = new PdfPTable(3);

        Checks.cResults.keySet().iterator();

          Iterator<String> iteratorSectionC = Checks.cResults.keySet().iterator();
        while(iteratorSectionC.hasNext()) {

            String key=(String)iteratorSectionC.next();

            int value=(int)Checks.cResults.get(key);

           // Log.d("mensa", "mi Pregunta iteratorSectionC::\n"+key+" valor::"+value);

            //Paragraph pN = new Paragraph(key+" val::"+value);
            //document.add(pN);
            table.addCell(key+" val::"+value);

        }

        //add empty cells

        int difference = numberOfIdealCells - numberOfCells;

        if (difference > 0) {

            for(int i = 0; i<difference ; i++){
                table.addCell("");

            }
        }



        return table;
    }

My problem is that I need to pass my iterator for each different block, but I can't seem to find a proper way to pass it to my function.

Shall I make it a static variable and according to case A,B,C and use the corresponding iterator?

Iterator<String> iteratorSectionC = Checks.cResults.keySet().iterator();

Or how can I pass it in a function parameter?

\$\endgroup\$
3
\$\begingroup\$

Getting rid of the duplication is fairly simple, since the three methods were actual duplicates, aside from the access to the Map.

To refactor : in the createTableA() method, introduce local variable from the expression that gets the map, then extract method, that takes the local variable as a parameter. Then reimplement createTableB() and createTableC() to also call the new method. In createTableA() you can then inline the local variable again.

I've also done some other things. I've replaced the calculation of the ideal number of cells (as comments in the code already suggested). And I've extracted a few methods that help readability. Actually this made me wonder wether the Paragraph part (see my addSpace() method) really belongs in this method, since it has nothing to do with creating a table.

I've also trimmed some unnecessary code (casts, and creating an unused iterator), and made use of the foreach loop structure rather than your original while loop. I've introduced an explaining constant for the number of columns, and trimmed the logging and comments that added noise (they were in Spanish, and didn't help me, so too bad :) )

The methods like createTableA() should probably be inlined in the client code.

private static final int COLUMNS = 3;

public static PdfPTable createTableA() {
    return createTable(Checks.aResults);
}

public static PdfPTable createTableB() {
    return createTable(Checks.bResults);
}

public static PdfPTable createTableC() {
    return createTable(Checks.cResults);
}

private static PdfPTable createTable(Map map) {
    addSpace();

    PdfPTable table = new PdfPTable(COLUMNS);
    for (Object key : map.keySet()) {
        table.addCell(key + " val::" + map.get(key));
    }
    addPaddingCells(table, paddingCells(map.size()));
    return table;
}

private static int paddingCells(int totalCells) {
    return (totalCells + COLUMNS - 1)/ COLUMNS * COLUMNS - totalCells;
}

private static void addSpace() {
    addEmptyLine(new Paragraph(), 3);
}

private static void addPaddingCells(PdfPTable table, int number) {
    if (number > 0) {
        for(int i = 0; i< number; i++){
            table.addCell("");
        }
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ On a second inspection I also noticed that the if check in addPAddingCells() is superfluous. \$\endgroup\$ – bowmore May 7 '13 at 5:23
1
\$\begingroup\$

It is not clear what you are realy trying to do. But if I understand you right, you want to save a lot of duplicate code while creating different tables. I added two variables to the table creation method, which could now create the different tables without the code duplication.

Iterators are meant to be traversed only once. Maybe your problem arose from another point of view what iterators can be used for?

Please correct me if I misunderstod you and clearify your question to get more and better answers.

public static void HXLGRMP(){
    tableOne = Class.createTable(Checks.aResults, 1)
    tableOne = Class.createTable(Checks.bResults, 2)
    tableOne = Class.createTable(Checks.cResults, 3)
}


public static PdfPTable createTable(type_of<Checks.Results> results, int tableNumber) {
    //empty space
    Paragraph paragraph = new Paragraph();
    addEmptyLine(paragraph, 3);

    int numberOfCells = 0;
    int numberOfIdealCells = 0;

    //int
    numberOfCells = results.size();
    numberOfIdealCells = numberOfCells;  

    Log.d("mensa", "numero de preguntas : "+numberOfCells);

    //TODO REFACTOR THIS LOGIC TO KNOW IF NUMBER OF CELLS OK!
    if (numberOfCells %3 != 0) {
        Log.d("mensa", "no lo es");
        numberOfIdealCells +=1;
        numberOfIdealCells +=1;
    }

    Log.d("mensa", "sikas");
    Log.d("mensa", "numero de preguntas afters: "+numberOfIdealCells);

    // a table with three columns
    PdfPTable table = new PdfPTable(tableNumber);

    Iterator<String> iteratorSection = results.keySet().iterator();
    while(iteratorSection.hasNext()) {

        String key=(String)iteratorSection.next();

        int value=(int)results.get(key);

        // Log.d("mensa", "mi Pregunta iteratorSection::\n"+key+" valor::"+value);
        //Paragraph pN = new Paragraph(key+" val::"+value);
        //document.add(pN);
        table.addCell(key+" val::"+value);
    }

    //add empty cells
    int difference = numberOfIdealCells - numberOfCells;

    if (difference > 0) {
        for(int i = 0; i<difference ; i++){
            table.addCell("");
        }
    }

    return table;
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.