Dariusz Mydlarz

Dariusz Mydlarz

Software Craftsmanship, Project Management & Producitivity

QR code

Elegant Objects in a Simple Example

I believe that maintainability is a key feature of the code you produce. It is good when your code works. But it is even better when it is maintainable in the long run. For many years I was not happy with my code. I was learning about encapsulation, SOLID principles and immutability. But none of this lessons taught me as much as reading Yegor Bugayenko blog and - what is more - his book. In this blog post, I want to give you a short example which shows his point of view so you can grasp the idea.

November 27, Krakow, Wawel Castle - https://www.instagram.com/p/BcBxfDzDhm0
November 27, Krakow, Wawel Castle - https://www.instagram.com/p/BcBxfDzDhm0

I had a very clear goal recently. I wanted to transform strings in a way that ones without white spaces are not changed, and the others are double quoted. So when I had string krakow I want to stay it as it is, but when I had string san fransisco I wanted transform it into "san fransisco". I believed there must exist something in Apache Commons Lang project for that. Unfortunately, it wasn’t. But I found the required piece of code in Apache Commons Exec.

I didn’t want to grab the whole library into my project, just this small piece of code. Previously I would just create my own StringUtils class and copy the method there*. Then I would just call StringUtils.quoteArguments in any place needed. But I didn’t want to flood my codebase with static methods. I knew there must be a better approach.

So what did I do? Well, I just created an appropriate object. An object, which takes a text as a constructor argument and exposes one method, that adds quote for me.

How does it look like?

/**
 * Put quotes around the given String if necessary.
 * <p>
 * If the argument doesn't include spaces or quotes, return it as is. If it
 * contains double quotes, use single quotes - else surround the argument by
 * double quotes.
 * </p>
 * <p>
 * Copied from Apache Commons Exec: http://commons.apache.org/proper/commons-exec/
 */
class QuotedString {
    private static final String SINGLE_QUOTE = "\'";
    private static final String DOUBLE_QUOTE = "\"";

    private final String argument;

    public QuotedString(String argument) {
        this.argument = argument;
    }

    public String toString() {
        String cleanedArgument = argument.trim();

        // strip the quotes from both ends
        while (cleanedArgument.startsWith(SINGLE_QUOTE) || cleanedArgument.startsWith(DOUBLE_QUOTE)) {
            cleanedArgument = cleanedArgument.substring(1);
        }

        while (cleanedArgument.endsWith(SINGLE_QUOTE) || cleanedArgument.endsWith(DOUBLE_QUOTE)) {
            cleanedArgument = cleanedArgument.substring(0, cleanedArgument.length() - 1);
        }

        final StringBuilder buf = new StringBuilder();
        if (cleanedArgument.contains(DOUBLE_QUOTE)) {
            if (cleanedArgument.contains(SINGLE_QUOTE)) {
                throw new IllegalArgumentException("Can't handle single and double quotes in same argument");
            }
            return buf.append(SINGLE_QUOTE).append(cleanedArgument).append(
                SINGLE_QUOTE).toString();
        } else if (cleanedArgument.contains(SINGLE_QUOTE) || cleanedArgument.contains(" ")) {
            return buf.append(DOUBLE_QUOTE).append(cleanedArgument).append(
                DOUBLE_QUOTE).toString();
        } else {
            return cleanedArgument;
        }
    }
}

I didn’t change the original code at all, but I it does what I wanted. Transforms: krakow into krakow and san fransisco into "san fransisco".

Notice the benefits I gained:

  1. The object is lazy - it doesn’t perform any calculations if not needed.
  2. It is easy to test.
  3. It is small, so it is easy to maintain in the future.
  4. It is easy to use in collections. You can wrap multiple items in a collection with the object, but in the end use just a few of them. This way you will not perform heavy calculations on the entire collection if not needed.
  5. It is immutable.
  6. It is cheap to create. Java is designed to create new objects.

    Object creation in Java due to its memory allocation strategies is faster than C++ in most cases and for all practical purposes compared to everything else in the JVM can be considered “free”.

    https://softwareengineering.stackexchange.com/a/149569/121218

Do you get the idea? Creating small, cohesive classes is much better than creating another commons or utils monsters. Isn’t it?


* According to the library license