Oh, all that entitlement…

There was a tiny tweet yesterday, resurrecting a talk from Christin:

Here’s the direct link to the talk: “Hibernate should be to programmers what cake mixes are to bakers: beneath their dignity.”.

I’d like to emphasize that I would have maybe thought so some 15 years back, too.
Today I cannot understand this whole setup of patronizing so many things at once.

The tweet linked above cause many threads. You have to digg through them a bit, but the most interesting ones are the discussions around Gavins, Gunnars and Johannes’ answers.

I am not a Hibernate fanboy, I’m a regular Hibernate user though. I’m however very much a database fanboy, as long as there is a great, declarative query language (PSA: I work for Neo4j, use Cypher a lot to provide and work in a team that creates an Object Graph Mapper (OGM)).

I firmly believe in the fact that there are no silver bullets and having only one idea is a super dangerous situation:

Having said that, I actually don’t to take the discussion about SQL and Cypher vs ORM and OGM any further.

I’d like to point out that I find several things with the heated discussion yesterday more than odd:

We all started somewhen and somewhere. With no knowledge, some knowledge, good or bad intuition. But we started and learned stuff. As a matter of fact, I just wrote about it the other week. One very important step on the way of becoming a senior something is actually realizing that other people may have less or other knowledge and working with that, helping them, instead of condescending them.

Second: I like cake mixes. I also like fresh, hand made apple pie.

Most of the years, I take the time with the kids to bake a cake for my wife’s birthday. You know what: We go and buy a cake mix and the missing, liquidish ingredients, mix the stuff up and spent the time we saved on decorating the cake, our table and whatnot.

On the other hand, going out for a coffee, either in a café or visiting friends being great with baking: Most awesome! And sometimes, when I’m really in for the mood, I do bakery with all the things necessary myself.

Having the possibility to chose between these options is entitlement, not everyone has: There are enough people that don’t have these simple choices, for whatever reasons.

Leaving the analogies behind: In now nearly 20 years of working in IT, I always had choices and good options. I could try out various frameworks, far beyond the “getting started guide.” Not on my spare time, but on the job. This such a big advantage. Yes, I know there are voices that people have to invest their own time to learn, but you know what? Being able to do this… well is entitlement, too. It’s ok to only work a regular 8 hours shift.

Today I understand better that people just want to use things. Many people work in projects under such high pressure, there’s just no room to get everything used right and even less room to recreate all the stuff by themself.

I think we should be happy, that we can choose from so many actually good ready to use ingredients, being it Hibernate, Spring, Grails, Spring Data, Java EE or whatever these are called in the Ruby, PHP, JavaScript etc. worlds. We can even be more happy when we work in places that gives us time to get things right. Either using frameworks correctly or add the custom bells and whistles needed.

Feel free to rant about all the stuff you want. But rant about actual bugs and inefficiencies and don’t start from a patronizing analogy.

Featured image: unsplash-logoDilyara Garifullina

| Comments (0) »

13-Jul-19


Never not learning…

Sometimes my teammate Gerrit teases me “Don’t you know this and that as a Java Champion?”… Of course I don’t. Honestly, the older I get, the better I know that I know nothing.

This week has been interesting. At first, I stumbled upon something like this

A shortcut to System properties

public interface Stuff {
 
    String SOMETHING_ENABLED_KEY = "stuff.is.enabled";
    static boolean isSomethingEnabled() {
 
        return Boolean.getBoolean(SOMETHING_ENABLED_KEY);
    }
}

And I was like: “How the hell do I set SOMETHING_ENABLED_KEY too true?!”, only having Boolean#parseBoolean(String s) in mind, which “parses the string argument as a boolean.”

Boolean#getBoolean(String s) actually goes to the Systems properties and checks for the existence of a property named s as described in the docs: “Returns true if and only if the system property named by the argument exists and is equal to the string ‘true’.”

I honestly didn’t expect such a shortcut in a wrapper class. To my surprise, those exists for other wrappers like java.lang.Long, too.

See related twitter thread:

But, the week just got more interesting.

Things that are and aren’t enums (aka isEnum())

See this gist right here: EnumTests.java. To understand this, you have to know a bit more about EnumTypes.

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.

I guess many people stop reading there and don’t go further into the planet example.

Enums are very versatile things. They can work as strategies and are one of the easiest and actually safest to use singletons in Java. They can also implement interfaces. I use this here in ParameterConversion.java to encapsulate a strategy and providing one defined instance only. Joshua Bloch talks about this in Effective Java Third Edition in detail.

But anyway, that’s not the point. Instances of an enum (that is, one of the “constants”) can overwrite the enums methods. As soon as you do this, they are realised as an anonymous, inner class. And with it, asking for EnumType.ENUM_CONSTANT.class.isEnum() will return false.

Brian Goetz is totally right here, even though it’s embarrassing for me:

I could have asked “EnumType.class, are you an enum?” and that holds correctly true. The enum constants however doesn’t promise that. If you want to check wether a thing is an instance of an enum type, than just do this: EnumType.ENUM_CONSTANT instanceof Enum or if you have an object of unknown type, do this Enum.class.isAssignableFrom(aThing.getClass())

I learned so much from the answers to my tweet here, you should check them out:

Twitters UI messes the threading up a bit, so I highlight that one here, from Joseph Darcy:

This old Oracle Blog is a great read: So you want to change the Java Programming Language…

And now what?

On to the next week, onto more learning, more development. Don’t let titles or honours impress you too much. We all learn new stuff, even in old things, each day. And I do think that’s a very good thing.

Title photo: unsplash-logoKimberly Farmer

| Comments (1) »

05-Jul-19



Don’t stop writing code comments

TL;DR: The older I get, the more diverse projects I have seen, the more often I refrain from giving someone an absolute advice. In almost any cases, there are many aspects to consider. In times when people hardly read documentation and often only headlines, an advice like “Stop Writing Code Comments” guarantees some clicks, but isn’t absolutely for the good nor appropriate in all scenarios.

At the beginning of this week, @java tweeted this:

Pointing to this blog post Stop Writing Code Comments. Brian seems to be a big apologist of the clean code movement. I can understand this to some extends, but moved away from “keep methods as small as possible” and similar quiet some extend. Sometimes it’s just necessary and as long as the logic in a bigger method stays testable, I don’t see an issue. And apart from that, what’s dirty code anyway?

What and how to comment

But I want to address some of the methods in the Medium post above. The name of the method is indeed good. But imagine the following:

/**
 * Finds all the employees with a given status. The method will return all employees with a given status, regardless
 * when they joined the company. The returned list will be immutable, changes to the employee objects will not be tracked.
 * 
 * @param status The employment status of the employees to find. Must not be null.
 * @return A list of employees with the given status or an empty list of no employee has the given status
 * @throws IllegalArgumentException when the status is literal null
 */
List<Employee> getEmployeesByStatus(Status status) {
  ...
}

As a user of that method I know now exactly what to pass to the method and what I can expect to return. I have an idea that the list may be empty, but is never null.

The employee class is badly named, that’s nothing to fix with a comment indeed. But chose a better naming and add some meaningful comment and things look bright:

/**
 * A person that is currently employed at the company. Instances of this class are not attached to the database
 * and represents a current employee purley from the business domain and can be savey passed around services.
 *
 * For other types of employees, see {@link RitiredEmployee} or {@link FiredEmployee}
 */
public class CurrentEmployee {
}

I do actually like this part:

public void sendPromotionEmailToUsers() {
  calculatePrices();
  compareCalculatedPricesWithSalesPromotions();
  checkIfCalculatedPricesAreValid();
  sendPromotionEmail();
}

There’s nothing much to add here. But let’s focus on sendPromotionEmail. It’s intentions are pretty clear, but I think it can be improved:

/**
 * Sends an email to all users eligible for a promotion. It does not include any retry mechanism, an e-mail is considered
 * sent when the configured SMTP server acknowledged the e-mail
 * An exception is thrown when the SMTP server is not reachable.
 *
 * When no users are eligible for promotion, no emails are sent
 * @see #getEmployeesByStatus
 * @throws RuntimeException when the SMTP Server could not be contacted
 */
void sendPromotionEmail() {
}

By coincidence I found this paper on The Use Of Sub-Routines In Programmes by David Wheeler. My friend Lukas quoted it in his talk 10 Reasons Why we Love Some APIS and Why we Hate Some Others. The paper – being from 1952 – summarises things neatly:

[…] sub-routines are very useful – although not absolutely necessary – and that the prime objectives to be born in mind when constructing them are simplicity of use, correctness of codes and accuracy of description. […]

Neither small and grokable methods nor comments alone help to create an understandable software system. One needs both.

On the obsolesce of comments

Brian speaks a lot about comments that becomes invalid and outdated. In my opinion, comments just needs to be treated as deliverable artefact as well and needs to be refactored with the code being documented. It’s easy as that.

Useless comments

I wholeheartedly agree with large chunks of commented code: Remove it, please! That’s what a version control system is for.

Regarding TODO comments: I use them occasionally to remind me of things I need to come back to in the future, which would block me from more important things at the very moment.
However, one alternative solution to that is to write failing tests: Those reminds you much better of things to fix.

Title photo by Marc Schäfer on Unsplash

| Comments (2) »

04-Jun-19


Separation of concerns in Spring applications

TL;DR: Don’t surprise your fellow developers.

Yesterday I learned – or realized again, don’t know – that one can add @CompenenScan to all Spring components and not only to @Configuration components:

It’s also ok to annotated methods of standard components with @Bean and turn them into weird factory components (Those being processed in “light” though, as Marten reminded us.)

I see several issues here, the dilution of concern’s being my primary. I can get a quick overview of all services of an application with my IDE looking for @Service or whatever. The same with configuration. That helps me a lot not to have to think about things.

I spent a considerable amount of time yesterday helping a friend debugging a weird @SpringBootTest. He wanted to exclude some services from being started and only test some. The first impression was: He tried this by specifying them on the classes attribute of @SpringBootTest. That’s not what that attribute does. That attribute is used to point the test context to configuration classes.

To include or exclude components from being started, one uses @ContextConfiguration, also from the test package. It has include and exclude.

So we added this and removed the classes from @SpringBootTest attribute. And: Nothing worked anymore. Wtf? After some digging it turned out, that those services mentioned on that attribute – while clearly named and annotated service – also configured more component scanning and the module did not have a @SpringBootApplication, so the test context couldn’t figure out about the components without being explicitly told to.

Given the fact that the project in question was just a bit older than a year, I think it’s already legacy and not in a good sense: A new developer joining that team would be have a super hard time figuring out what’s happening and why? Things are being named in one way and do something else or something in addition.

Go figure what happens next: It’s always Springs fault, of course.

Well, this time I’d say it’s quite dangerous indeed that all components contribute to the application context and not only @Configuration classes.

Imagine a library, containing some cool services. When you add this library via a custom starter, you would be hopefully aware, that the starter can add many things to your context. You could however be explicit and write down your own @Configuration and return new AwesomeLibraryService() from within a @Bean method. The AwesomeLibraryService could be annotated with an arbitrary @ComponentScan and scan the kitchen sink, the JDK and all the rest, including a blockchain mining library. Probably not what you want.

Anyway, we all are responsible developers, everyone does DDD and writes nice, clean micro services.

My impression of real world projects, especially in big cooperates, is a another. I always stumble upon the same issues:

  • Issues with dependencies
  • Incompatibile versions
  • Cargo cult: A configuration hacked together from various sources is passed on all the time

People are gonna reuse the stuff the find somehow working in projects, whether it’s good or bad.

It’s a seniors developers responsibility to make sure that things have well defined concerns. I am sure that it is impossible to prevent cargo cult, but one can make it a bit safe.

Title photo by Franck V. on Unsplash.

| Comments (1) »

17-May-19