Java Developer

ot-clean, Refactoring and cleaning DSL (2/4)

In previous post we’ve removed dependency. Now let’s try to use some Java 8 sugar.

Step 3: Functional approach

We can significantly reduce the amount of code that is needed to define cleanable.

Before

Cleanable MAVEN = new Cleanable() {

    @Override
    public void clean(final Delete delete, final Path path) {
        if (this.match(path)) {
            delete.file(path.resolve("target"));
        }
    }

    @Override
    public boolean match(final Path path) {
        return path.resolve("pom.xml").toFile().exists();
    }

    @Override
    public void display(final Path path, final Console console) {
        console.print(
            String.format(
                "[Maven]: %s", path
            )
        );
    }

};

After

Cleanable MAVEN = new Definition(
    "Maven",
    path -> path.resolve("pom.xml").toFile().exists(),
    (delete, path) -> delete.file(path.resolve("target"))
);

This is still the same code as before but we implemented small sugar object that is able to take care of all stuff for us. Let’s call it Definition.

final class Definition implements Cleanable {
    /**
     * Name of the cleaning definition.
     */
    private String name;

    /**
     * Matching behaviour.
     */
    private Function<Path, Boolean> matcher;

    /**
     * Cleaning behaviour.
     */
    private BiConsumer<Delete, Path> cleaner;

    /**
     * Ctor.
     *
     * @param cname Name of the cleaner.
     * @param cmatcher Matching behaviour.
     * @param ccleaner Cleaning behaviour.
     */
    public Definition(
        final String cname,
        final Function<Path, Boolean> cmatcher,
        final BiConsumer<Delete, Path> ccleaner
    ) {
        this.name = cname;
        this.matcher = cmatcher;
        this.cleaner = ccleaner;
    }

    @Override
    public void clean(final Delete delete, final Path path) {
        if(this.match(path)) {
            this.cleaner.accept(delete, path);
        }
    }

    @Override
    public boolean match(final Path path) {
        return this.matcher.apply(path);
    }

    @Override
    public void display(final Path path, final Console console) {
        console.print(
            String.format(
                "[%s]: %s", this.name, path
            )
        );
    }
}

It looks bit overcomplicated but the best part will start soon.

Step 4: Functional expressions

Let’s extract some functions into the named helpers

Cleanable MAVEN = new Definition(
    "Maven",
    If.fileExists("pom.xml"),
    Then.delete("target")
);

Below you can find source code of the helpers.

/**
 * Collection of behaviours for matching purposes.
 */
final class If {

    /**
     * Returns true if file exists.
     *
     * @param name Name of the file.
     * @return Matching behaviour.
     */
    static Function<Path, Boolean> fileExists(String name) {
        return path -> path.resolve(name).toFile().exists();
    }

}

/**
 * Collection of behaviours for cleaning purposes.
 */
final class Then {

    /**
     * Executes cleanup using list of paths. RegExps are allowed.
     *
     * @param deletes List of paths.
     * @return Deleting behaviour.
     */
    static BiConsumer<Delete, Path> delete(String... deletes) {
        return (delete, path) -> {
            Yconfig yconf = new Yconfig();
            yconf.setDeletes(Lists.newArrayList(deletes));
            yconf.filesToDelete(path).forEach(delete::file);
        };
    }

}

Now let’s try to do reduce some code and make it less error prone

The ot-clean series

This blog post is one of the series about the ot-clean. Simple open source tool that maintains your projects directories cleaned from all the garbage. Feel free to look at the source code or readme page for more information. You can also submit pull request or post suggestion. This text participates in open source blogging competition.

Project status

Build Status

All posts from the ot-clean series


Like it? Share it on , , ,

About the author

Grzegorz Gajos, Software Architect with international consulting and programming background. Co-founder of Open Tangerine Software House. Quality evangelist. An experienced entrepreneur, out of the box thinker and problem solver.