Common interface with different return types I am creating a small app working on file system. The user can choose a directory and than, application get one of the possible result (examples):


return number of lines in all *.java files
return number of lines in all *.java files without comments
return number of all classes
return number of ifs etc...


Because I want to follow the single responsibility principle, and because all these functionalities have something in common, I want to create one class for each functionality (using commons.io DirectoryWalker) under a common interface. That's why I find such an interface useful:

**
 * Common interface for counting classes (lines, words, classes, etc...) 
 */
public interface Counter {
    /**
     * count required things starting from startDirectory, recursively or not, 
     * and consider only specified extensions 
     */
    int count(File startDirectory, boolean recursive, List&lt;String&gt; fileExtensions);
    int count(File startDirectory, boolean recursive);
}


Now, the user can simply create some collection with counters, create and add new counter easily, iterate etc.

Questions:


Of course it is just a simplification, but do you think that the main idea of using an interface here is reasonable?
Maybe I will have some methods which will return something different than int - for example, Map with pairs, or a list of the ten longest files. In this case my interface is not correct. What should I do in such case? Maybe the interface's method should return Object like this:

Object count(File startDirectory, boolean recursive);


But this seems bad to me as it will lead to some unfriendly casting when parsing the returned value (Object). I can create some special DTO object like the below which will contain all possible "answers":

public class CounterDTO {
    public int numerOfLines; // used for counters counting lines
    public int numberOfIfs;  // used for counters counting if statements
    public Map&lt;File, Integer&gt; linesInFiles;  // ... File -&gt; number of lines
    public List&lt;File&gt; longestFiles; // used for indicating files with maximal number of lines
    // and so on...
}


Then the interface method would look like:

CounterDTO count(File startDirectory, boolean recursive);


Is this OK or is there a better way?
Normally when you need "different return types", you can use generics. However, since you want these Counters to be in a List of some sort, using generics goes out the window since a List cannot be defined properly to contain both Counter&lt;List&lt;File&gt;&gt; and Counter&lt;Integer&gt;, so the only solution would be to have a List&lt;Counter&lt;?&gt;&gt; in which case the reason for using generics in the first place is lost.

Your CounterDTO class makes sense if a Counter counts more than one of the things. If the counter is only meant to return an int or a list of files, then using a CounterDTO is quite useless since many fields will be null.

Regarding Banthar's comment to your question, you could modify your existing interface to

int count(List&lt;File&gt; files);


It would then be the job for a single utility method (or two) to create a list of files from these parameters: File startDirectory, boolean recursive, List&lt;String&gt; fileExtensions.

As for the question about return type... If you need an interface for this or not depends on how you are using these counters. And also: Which possible counters are there? If you have one counter for returning total line count and one for returning a Map&lt;File, Integer&gt; of line counts, then you don't need two different counters. Since you need to know all the line counts in all the files to know the total line count, using a CounterDTO makes perfect sense here.