Java 8 Optional

A short post to capture for posterity the Optional syntax when you want to safely pass a nullable variable to a method or function that cannot handle nulls:

String var = Optional.ofNullable(someStupidNullable).map(SomeType::someMethod).orElse(null);
Advertisements

Concise List Creation in Java

I came across some interesting code today to set up a list of objects in Java that I thought was worth highlighting for its conciseness.

List<ServerAddress> list = new ArrayList<>() {{
        add(new ServerAddress("127.0.0.1", 27017));
        add(new ServerAddress("127.0.0.1", 27027));
        add(new ServerAddress("127.0.0.1", 27037));
    }
}

Essentially we subclass a new list instance as an anonymous inner class with an initializer block (since, being anonymous, it cannot have a constructor). In that initializer, we call add on the list for each item we wish to add. I thought this was a good, concise way of creating the populated list, allowing fluent API style without the need for external libraries like op4j.

Refactoring – towards a better definition

According to SAFe, refactoring is

“modifying an entity, such as a module, method or program in such a way that it’s external appearance, i.e. its functionality, remains unchanged.”

Refactoring, the author says, may increase speed or address security concerns. According to the preface of Martin Fowler’s book ‘Refactoring’, refactoring is

“changing a software system in such a way that is does not alter the external behaviour of the code yet improves the internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs. In essence, when you refactor you are improving the design of the code after it has been written.”

Both agree that refactoring leaves the system ‘externally’ unchanged. Both agree it makes no sense to say, as I have heard developers say in the past, ‘I want to refactor the code to add this new feature for the end user.’ That is not a refactoring; it is a new feature. I have a question about this. Are performance improvements such as adding internal caching or adding an index examples of refactoring? SAFe thinks so. But is a performance improvement not a change for the end user? Moreover, you can make a horrible mess in the code when you implement a performance improvement. Is it helpful to call that a refactoring? Do we want to be able to say ‘I refactored the IdLookup component to make it faster, but I made a mess; we need to refactor it again to make it cleaner.’ Performance improvements are non-functional improvements or, better, quality improvements that affect external users. This is not exactly refactoring, which has a focus on the ‘internal’.

What about moving configuration from code to an external config file, to improve maintainability or flexibility? This is another example of refactoring given by SAFe. I can see how, from a certain point of view, this could be thought of as an ‘internal’ change. But some ‘external’ stakeholders will care greatly about this change. The time it takes to deploy a configuration change can be greatly affected by externalizing configuration from a hard-coded value, since the code does not have to be recompiled and rebuilt. Build and package enhancements are quality improvements that affect external stakeholders such as testing and operations, which is not, strictly speaking, refactoring.

When we do TDD, we say we ‘refactor’ after each passing test. What does this really mean? At it simplest, this typically involves removing duplication, reducing complexity, applying certain patterns, fixing style violations, and so forth. Note that these are quality attributes of the system that are generally measurable with static analysis and code review. And there is a stakeholder who cares about these qualities; the dev team as a whole, the team lead, or, better, QA.  These improvements are about code quality, technical debt, and primarily affect the internal development team.  These are true refactorings.