Inspired by FilenameFilter.java, I want to use similar approach/design pattern to solve my problem. I have select files from sftp server based on:
- If it is older than n days
- If it is older than n days and its name is in certain pattern.
I have defined a functional interface SemanticFileFilter as below:
public interface SftpFileFilter
{
boolean accept(LsEntry sftpFile);
}
LsEntry for sftp is basically something like File in java.
Wanted to define SftpFileFilterFactory to get all implementation of SftpFileFilter at one place like below:
public class SftpFileFilterFactory
{
public static final SftpFileFilter OLD_FILE_FILTER = new SftpFileFilter()
{
//ERROR: because Interface function method should take only 1 parameter
//@Override
public boolean accept(LsEntry lsEntry,int nDays)
{
//checks if files if older than nDays
}
};
public static final SftpFileFilter PATTERN_MATCH_OLD_FILE_FILTER = new SftpFileFilter()
{
//ERROR: because Interface function method should take only 1 parameter
//@Override
public boolean accept(LsEntry lsEntry,int nDays, String pattern)
{
//checks if files if older than nDays and matches pattern "pattern"
}
};
}
How do I design my interface's function method or factory implementation so that in future if similar more filters needs to be defined, I don't need to bother much in code changes but just define new filter.
Also we should be able to chain filters. That is to say define one filter for older files and another for pattern matching. If both needs to used they should be able to chained together and hence both could be used.
Your problem reminds
Commanddesign pattern. You need to implement different conditions and to provide additional parameters you can use constructors and create classes or useJava 8lambda expressions. See below example:These objects are too small and there is not need to create factory for it. You can create and use them if it is necessary. Of course, you can create factory which creates some predefined filters:
It is a good separation between filter implementations and client code which does not know anything how filtering by name is implemented and can be easily exchanged.
In
Java 8you can usejava.util.function.Predicatedirectly or extend it by your interface: