mercredi 18 mars 2020

What is a smart solution to handle a list of different classes implementing an interface in this Spring Boot application?

working on a Java Spring Boot application I am finding the following problem and I don't know if exist a pattern that can solve my problem.

I will try to explain my situation in details and how I am trying to solve this situation (with no concrete result at the moment).

I have this DTO class named ExcelTrendTabGeneralDTO:

public class ExcelTrendTabGeneralDTO {

    private String excelDocumentName;
    private String excelTabName;

    private List<ExcelTabInterface> tabTrendList;

    public ExcelTrendTabGeneralDTO() {
        super();
    }

    public ExcelTrendTabGeneralDTO(String excelDocumentName, String excelTabName,
            List<ExcelTabInterface> tabTrendList) {
        super();
        this.excelDocumentName = excelDocumentName;
        this.excelTabName = excelTabName;
        this.tabTrendList = tabTrendList;
    }

    .............................................................
    .............................................................
    .............................................................
    GETTER AND SETTER METHODS
    .............................................................
    .............................................................
    .............................................................
}

In this class there is the core of my problem. As you can see it contains this field:

    private List<ExcelTabInterface> tabTrendList;

That, at the moment, I defined as an empty interface:

public interface ExcelTabInterface {

}

It is a list of ExcelTabInterface (that is an interface, now I explain why and what I am trying to do). At the beginning instead this ExcelTabInterface I had a specific concrete type (a class) but I replaced it with an interface because this list could contain different kind of objects instances of classes implementing this interface (this was my idea).

So for example I had a class like this (named CompVibrAndTempDTO):

@Description(value = "DTO for the \"Vibration Monitore\" Excel tab")
public class CompVibrAndTempDTO extends ExcelTabAbstractDTO implements ExcelTabInterface {
    private String tempReadingPointA;
    private String tempReadingPointB;
    private String tempReadingPointC;

    ....................................................................
    ....................................................................
    ....................................................................
    CONSTRUCTOR AND GETTER AND SETTER METHODS
    ....................................................................
    ....................................................................
    ....................................................................
}

Ok...the idea seems to work (I have not syntax error in my IDE).

And here the problem: then I have a repository class that uses JdbcTemplate to perform query on my database:

@Repository
public class ExcelRepositoryImpl implements ExcelRepository{

    @Autowired
     private JdbcTemplate jdbcTemplate;

    @Override
    //public List<CompVibrAndTempDTO> findCompVibrAndTempTab() {
    public List<ExcelTabInterface> findCompVibrAndTempTab() {

        String SELECT_COMP_VIBR_AND_TEMP_TAB = "SELECT * FROM TREND006";

        List<ExcelTabInterface> resultList = jdbcTemplate.query(SELECT_COMP_VIBR_AND_TEMP_TAB, new CompVibrAndTempMapper());

        return resultList;

    }

}

So as you can see I am performing a SQL query expecting to retrieve a list of objects implementing my ExcelTabInterface interface. The problem is that to build these objects I use a custom mapper class named CompVibrAndTempMapper implementing the Spring RowMapper interface.

So this is my custom mapper class:

public class CompVibrAndTempMapper implements RowMapper<ExcelTabInterface>{

    @Override
    public CompVibrAndTempDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
        ExcelTabInterface compVibrAndTempDto = new CompVibrAndTempDTO();

        SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat formatDate = new SimpleDateFormat("dd/MM/yyyy");
        SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm:ss");

        String dateStr = null;
        String timeStr = null;

        String dateFromDB = rs.getString("Time_Stamp");

        try {
            Date date = formatDateTime.parse(dateFromDB);
            dateStr = formatDate.format(date);
            timeStr = formatTime.format(date);      
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        compVibrAndTempDto.setDate(dateStr);
        compVibrAndTempDto.setTime(timeStr);
        compVibrAndTempDto.setTempReadingPointA(rs.getString("Sensor464DV"));
        compVibrAndTempDto.setTempReadingPointB(rs.getString("Sensor465DV"));
        compVibrAndTempDto.setTempReadingPointC(rs.getString("Sensor466DV"));
        ..........................................................................
        ..........................................................................
        ..........................................................................
        return compVibrAndTempDto;
    }

}

And here I have my problem. The problem is that it give me error on the setter methods because these methods are not defined in my interface (that is empty).

Ok I can insert these setter methods for my concrete DTO and I solve this error !!! BUT this partially nullifies my efforts to generalize my DTOs classes.

Because I have other DTOs classes implementing my ExcelTabInterface interface --> so I have to insert also the getter and setter methods of these others DTOs classes into my interface --> so I need to declare all the methods of a each DTOs into all my DTOs classes implementing ExcelTabInterface interface.

In theory I thing that a solution could be implement all the methods that I need to declare in the ExcelTabInterface interface in all my DTOs classes and implement as "do nothing" methods the mnethods that I have not to use but it seems to me pretty a mess.

What do you think about? Could be a viable solution or is it ugly as hell? Exist some patterns or something like this tha solve my problema in a neater way?

Aucun commentaire:

Enregistrer un commentaire