java - 重构扫描文件夹类(添加AllwaysPassesBlocker())

标签 java refactoring

我需要在 FolderScan 中创建一个新的构造函数,它采用“跳棋”列表。所有这些“跳棋”总是返回 true(应该编写新的跳棋列表,只返回 true。)
但问题是我不知道如何做到这一点而不分解程序的结构。

代码(FolderScan 和每个 Cheker):

class FolderScan implements Runnable {

    FolderScan(String path, BlockingQueue<File> queue, CountDownLatch latch,
            File endOfWorkFile) {
        this.path = path;
        this.queue = queue;
        this.latch = latch;
        this.endOfWorkFile = endOfWorkFile;

        checkers = new ArrayList<Checker>(Arrays.asList(
                new ExtentionChecking(),  new ProbeContentTypeCheking(), 
                new EncodingChecking() ));
    }

        @Override
public void run() {
    try {
        findFiles(path);
        queue.put(endOfWorkFile);
        latch.countDown();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

    private void findFiles(String path) {

    try {
        File root = new File(path);
        File[] list = root.listFiles();
        for (File currentFile : list) {
            boolean checksPassed = true;
            if (currentFile.isDirectory()) {
                findFiles(currentFile.getAbsolutePath());
            } else {
                for (Checker currentChecker : checkers) {
                    if (!currentChecker.check(currentFile)) {
                        checksPassed = false;
                        break;
                    }
                }

                if (checksPassed) {
                    queue.put(currentFile);
                }
            }
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


    private String path;
    private BlockingQueue<File> queue;
    private CountDownLatch latch;
    private File endOfWorkFile;
    private List<Checker> checkers;
}

class ExtentionChecking implements Checker {

    @Override
    public boolean check(File currentFile) {
        fileName = currentFile.getName().toLowerCase();
        Set<String> extensions = new HashSet<String>(Arrays.asList(".txt",
                ".pdf", ".doc", ".docx", ".html", ".htm", ".xml", ".djvu",
                ".djv", ".rar", ".rtf", ".tmp"));

        if (extensions.contains(fileName.substring(fileName.lastIndexOf(".")))) {
            return true;
        }

        return false;
    }

    private String fileName;
}

class EncodingChecking implements Checker {

    @Override
    public boolean check(File currentFile) {
        return detectEncoding(currentFile);
    }

    public static boolean detectEncoding(File file) {
        detector = new CharsetDetector();

        // validate input
        if (null == file) {
            throw new IllegalArgumentException("input file can't be null");
        }
        if (file.isDirectory()) {
            throw new IllegalArgumentException(
                    "input file refers to a directory");
        }

        // read input file
        byte[] buffer;
        try {
            buffer = readUTFHeaderBytes(file);
        } catch (IOException e) {
            throw new IllegalArgumentException(
                    "Can't read input file, error = " + e.getLocalizedMessage());
        }

        if(detector.setText(buffer) != null){
            return true;
        }

        return false;
    }

    private static byte[] readUTFHeaderBytes(File input) throws IOException {
        // read data
        FileInputStream fileInputStream = new FileInputStream(input);
        try {
            byte firstBytes[] = new byte[50];
            int count = fileInputStream.read(firstBytes);
            if (count < 5) {
                throw new IOException("Poor file!");
            }
            return firstBytes;
        } finally {
            fileInputStream.close();
        }
    }


    private static CharsetDetector detector;
}



class ProbeContentTypeCheking implements Checker {

    @Override
    public boolean check(File currentFile) {
        String mimeType = null;
        try {
            Path path = Paths.get(currentFile.getAbsolutePath());
            byte[] data = Files.readAllBytes(path);
            MagicMatch match = Magic.getMagicMatch(data);
            mimeType = match.getMimeType();
        } catch (MagicParseException | MagicMatchNotFoundException
                | MagicException | IOException e) {
            e.printStackTrace();
        }

        if (null != mimeType) {
            return true;
        }

        return false;
    }
}

问题:

  • 如何重构此代码 - 之后能够使 new AllwaysPassesBlocker() 和所有 Checers 返回 true?

最佳答案

始终返回 true 的检查器是

class UncriticalChecker implements Checker {
    @Override
    public boolean check(File currentFile) {
        return true;
    }
}

不过,将这样的检查器添加到检查器列表中是没有意义的。您不妨将该列表留空。

我不太明白为什么应该在FolderScan 的构造函数中构造检查器。将它们作为参数传递给构造函数似乎更自然。

FolderScan(String path, BlockingQueue<File> queue, CountDownLatch latch,
        File endOfWorkFile, List<Checker> checkers) {
    this.path = path;
    this.queue = queue;
    this.latch = latch;
    this.endOfWorkFile = endOfWorkFile;
    this.checkers = checkers;
}

然后,当您初始化FolderScan时,将其传递给检查器

List<Checker> checkers = new ArrayList<Checker>(Arrays.asList(
            new ExtentionChecking(),  new ProbeContentTypeCheking(), 
            new EncodingChecking() ));
FolderScan folderScan = 
    new FolderScan(path, queue, latch, endOfWorkFile, checkers);

或者,如果您希望创建一个返回所有文件的FolderScan,您可以向它传递一个空列表。

FolderScan folderScan =
    new FolderScan(path, queue, latch, endOfWorkFile, Collections.emptyList());

编辑: 我现在明白你想测试这门课。那么 UnriticalChecker 就有意义了。如果您想使用始终显示"is"的检查器来测试代码,请将其传递给构造函数:

List<Checker> checkers = Collections.singletonList(new UncriticalChecker());
FolderScan folderScan = 
    new FolderScan(path, queue, latch, endOfWorkFile, checkers);

关于java - 重构扫描文件夹类(添加AllwaysPassesBlocker()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15419681/

相关文章:

java - 如何检查文档是否已更新或插入到 MongoDB 中

refactoring - 限制 Webstorm 中的重构范围

c# - .NET 重构,DRY。双重继承、数据访问和关注点分离

Java 串口关闭 block

java - 仅单击的项目可见,并隐藏 RecyclerView 中之前的项目

java - 如何使用 Jquery 将多个值传递给 servlet

Swift:在另一个 switch 语句中重构 switch 语句

java - 需要建议使用合适的设计模式来创建 JAVA 对象

java - 在 Java 11 中重构使用不同对象的资源的尝试

java - com.sun.awt 包使用