Excellent programming is about function, not form
Are language architects, or would-be language architects, doing a disservice to Java by overthinking it? Let's not over-design our object models. After all, being fancy isn't their primary function.
It's a lot more important to recognize that programming is more about getting something done than writing in ways that model particular modes of thought. As a developer, you're far better off choosing to finish something useful as opposed to writing something with limited utility that will impress the peanut gallery.
Programming is about actually accomplishing something, not about conforming with a model of the real world.
It seems like advice we see every day now, as Java 8 matures and we see Java 9 features like "val" on the horizon. "Don't use mutators or accessors!," one TSS contributor offers, suggesting that one doesn't ask entities for information. ("Render information in presentable form," is his suggestion, ignoring the fact that accessors do exactly that.) Another author suggests the old chestnut of avoiding checked exceptions, because they make code "messy."
In and of themselves, these pieces of advice are only neutral - but they emphasize elegance over function. One imagines the author advocating avoidance of mutators using genetic algorithms to get a new Dog instance, in keeping with his dedication to modeling the real world... and it can get incredibly hairy. Just imagine:
// ***********************************************// // We don't know where dog1 and dog2 came from - // creation ex nihilo? We also have a constant // of a no-kill shelter in our namespace somehow. // ***********************************************// // This renders color in forms visible to the human eye ColorMedia media = dog.ColorSpace.HUMAN.media(); // ***********************************************// // dogConsumers is a list of shelters and people // who can take dogs off of our hands in case // they're not good enough for us // ***********************************************// List<Consumer<Animal>> consumers = dogConsumers(); // ***********************************************// // noKillShelter *has* to accept animals, cannot reject // hope this is tested well. // ***********************************************// consumers.add(noKillShelter); Optional<Dog> dog = Optional.empty(); while (!dog.isPresent()) { dog = dog1.mateWith(dog2); // note that media.print() has to take an Optional<HasColor> // and if empty, returns NOCOLOR? if (dog.isPresent() && !media.print(dog.get()).equals(ColorSpace.HUMAN.BLACK)) { // gross, have to use get() so we have a final reference final Dog dog0 = dog.get(); Optional<Consumer<Animal>> consumer = consumers.stream() .filter(s -> s.willConsume(dog0)) .findFirst(); if (!consumer.isPresent()) { // ew, icky get()! consumer.get().accept(dog0); dog = Optional.empty(); } } } // who needs "Dog dog=new Dog(Color.BLACK);" now!?!
Look, if your goal is to actually model the real world, that's great - it's what you'd actually want, probably, if you were trying to use genetics to get a dog with a brown coat, in line with how the real world works.
Programming doesn't usually want to rely on the Monte Carlo method.
But programming doesn't usually want to rely on the Monte Carlo method. When what we want is a Dog with a brown coat, we don't want to hope the parents' genders match up properly, or if the female's in heat, or if the mating is successful - we want a new Dog reference, with a brown coat.
Programming is about actually accomplishing something, not about conforming with a model of the real world; you're writing code for a CPU to execute, so you want to write instructions, not a choose-your-own-adventure novel.
Instructions are, and should be, clear. When I want to know how my son did in his basketball game, I don't ask him to fill out a page describing every play, nor do I hand him a form where he can fill out how many points he made - I ask him how many points he made, and unless he's feeling particularly sullen, he tells me.
Programming is simple. Java has a lot of idioms - common practices - that exist not only for cultural reasons, but logical reasons; those idioms work because they worked in the past, and they continue to work, and nobody has to wonder about it.
Write instructions for the computer, folks. That's not to say that you can't write clearly for the people around you, too; there's definitely a balance (or else we'd be writing assembly, rather than in a high level language like Java.) But don't decide that modeling the real world, or coding for the purpose of lower line counts, is more important than actually writing your program.