Should I place constants related to reading a specific type of file in the FileReader class or in a separate class?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/390774

Question

I am writing a class FileFoodReader (in java if that matters) that reads input from a file containing information about foods and their nutritional values. The file has to fulfill some requirements about how it is formatted. For example there must be a column containing food names and a column for each nutritional value. However other things can vary between files; for example the column names can vary and the "column index" of where the food names and different nutritional values are placed in the file can vary between files.

One file might have the column "Vitamin-A" at column index 5 and another file might have the same column named "A-Vitamin total" and placed at column index 14. Both of these columns refer to the nutrient Vitamin-A. My approach is to associate both of these columns with the Enum constant VitaminA with the help of a subclass to the abstract class FileConstants that is specific to each file and contains methods like Nutrient columnHeadingToNutrient(String columnHeading) and boolean canBecomeNutrient(String columnHeading). So both columnHeadingToNutrient("Vitamin-A") and columnHeadingToNutrinet("A-Vitamin total") would return an object of type VitaminA if the correct subclasses of FileConstants were used.

One file will already be available in the program and the relevant information about the file already be provided in a subclass of FileConstants. It is not likely that a user will want to change the file to read from very often or that the number of different files will be particularly big, but the user should have the option of adding a new file to read from that might differ in ways I described above. With user I mean a person that has access to the classes or at least can add new classes to the program.

The question I am asking myself is what is the best way of storing this information related to the file? Right now I'm choosing between either keeping my current approach using FileConstants or switch to subclassing FileFoodReader instead and provide the relevant file information in each subclass.
Right now the user would create a new subclass to FileConstants where it will have to implement the required methods and then an object of this subclass will be passed to the constructor of FileFoodReader or set with fileFoodReader.setFileConstants(fileConstants). For me it seemed more natural to not have to change the entire file reader every time one wanted to read a new file, especially since there is only a few things that are different between the files. But I have also read that it is generally a good idea in object oriented programming to try and keep the information relevant to a class in that class and not spread it out in different classes.

What do you think is the best approach to this, maybe I am doing it entirely wrong either way?

Was it helpful?

Solution

If you let the user decide which file format she wants to read, the FileFoodReader subclasses should not leak information about their format, they should just do one thing: read a file in their specific format.

If you use subclassing to keep common code in one place (for example, reading CSV formatted files vs. JSON vs. YAML vs. whatever), avoid creating complex dependencies between the abstract class and its subclasses, as they only make your code brittle and harder to change without adding much value.

For example, the information that the heading of column 5 is Vitamin-A is essentially redundant when part of the file definition is that column 5 will always specify vitamin A content, why pass that information around? Much better is when the FileFoodReader subclass has code that reads the string from column 5, converts it into a number in the appropriate unit and stuffs it into the domain object.

Licensed under: CC-BY-SA with attribution
scroll top