受FilenameFilter.java的启发,我想使用类似的方法/设计模式来解决我的问题。我根据以下内容从sftp服务器中选择文件:
我已经定义了一个功能接口SemanticFileFilter,如下所示:
public interface SftpFileFilter
{
boolean accept(LsEntry sftpFile);
}
sftp的LsEntry基本上类似于java中的File。
想要定义SftpFileFilterFactory以在一个地方获得SftpFileFilter的所有实现,如下所示:
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"
}
};
}
如何设计我的接口的函数方法或工厂实现,以便将来如果需要定义类似的更多过滤器,我不需要在代码更改中烦恼,只需定义新的过滤器。
我们也应该能够链接过滤器。也就是说为旧文件定义一个过滤器,为模式匹配定义另一个过滤器。如果两者都需要使用它们应该能够链接在一起,因此两者都可以使用。
你的问题提醒Command
设计模式。您需要实现不同的条件并提供其他参数,您可以使用构造函数和创建类或使用Java 8
lambda表达式。见下面的例子:
import java.util.ArrayList;
import java.util.List;
public class DesignPatterns {
public static void main(String[] args) {
List<SftpFileFilter> filters = new ArrayList<>();
filters.add(new OlderThanNDaysFilter(10));
filters.add(new NameSftpFileFilter("tmp.txt"));
// you can use lambda as well
filters.add((file) -> file.getName().length() > 0);
}
}
interface SftpFileFilter {
boolean accept(LsEntry sftpFile);
}
class OlderThanNDaysFilter implements SftpFileFilter {
private final int days;
public OlderThanNDaysFilter(int days) {
this.days = days;
}
@Override
public boolean accept(LsEntry sftpFile) {
return sftpFile.isOlder(days);
}
}
class NameSftpFileFilter implements SftpFileFilter {
private final String name;
public NameSftpFileFilter(String name) {
this.name = name;
}
@Override
public boolean accept(LsEntry sftpFile) {
return sftpFile.getName().equals(name);
}
}
这些对象太小,不需要为它创建工厂。如果有必要,您可以创建和使用它们。当然,您可以创建factory来创建一些预定义的过滤器:
class ConditionFactory {
private static final SftpFileFilter OLDER_THAN_TEN = new OlderThanNDaysFilter(10);
private static final SftpFileFilter PASSWORDS_FILE = new NameSftpFileFilter("passwords.txt");
public SftpFileFilter createOlderThan10Days() {
return OLDER_THAN_TEN;
}
public SftpFileFilter createPasswordsFile() {
return PASSWORDS_FILE;
}
public SftpFileFilter createNameFilter(final String name) {
return new NameSftpFileFilter(Objects.requireNonNull(name));
}
public SftpFileFilter createOlderThan(final int days) {
return new OlderThanNDaysFilter(days);
}
}
它是过滤器实现和客户端代码之间的良好分离,它不知道如何实现名称过滤并且可以轻松交换。
在Java 8
中,您可以直接使用java.util.function.Predicate
或通过您的界面扩展它:
interface SftpFileFilter extends Predicate<LsEntry> {
boolean accept(LsEntry sftpFile);
@Override
default boolean test(LsEntry lsEntry) {
return accept(lsEntry);
}
}