Java过滤器工厂实现
Posted
技术标签:
【中文标题】Java过滤器工厂实现【英文标题】:Java Filter Factory implementation 【发布时间】:2019-08-30 08:54:22 【问题描述】:受 FilenameFilter.java 的启发,我想使用类似的方法/设计模式来解决我的问题。我从 sftp 服务器中选择文件基于:
-
如果超过 n 天
如果它超过 n 天并且它的名称是某种模式。
我已经定义了一个功能接口 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"
;
如何设计我的接口的函数方法或工厂实现,以便将来如果需要定义更多类似的过滤器,我不需要在代码更改上费心,只需定义新的过滤器。
我们还应该能够链接过滤器。也就是说,为旧文件定义一个过滤器,为模式匹配定义另一个过滤器。如果两者都需要使用,它们应该能够链接在一起,因此两者都可以使用。
【问题讨论】:
【参考方案1】:您的问题提醒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);
【讨论】:
以上是关于Java过滤器工厂实现的主要内容,如果未能解决你的问题,请参考以下文章