Architect or Architect?

I recently discovered that there are two very different types of people in large companies, who (at least in case of my customer) both claim to be “architects”.

The one type is what I expect when I talk about architects. It is also what I mean when I claim to be an architect: Someone who helps a project to avoid the worst technical problems and solve those they fail to avoid. He or she does that by making the important technical decisions early enough but not too early.

The other type doesn’t really care too much about the project. Her focus instead is that of the enterprise. Often she concerns herself with questions like data security which the project might ignore, because it is not a direct concern of the project.

Both roles are important. Without the first role (it doesn’t have to be a single person) a project is in great danger of failing because it doesn’t meet it’s non-functional-requirements. Possibly because they aren’t even known to the project team. Without the second role the project might ignore non-functional-requirements that don’t come from the projects own stakeholder, but from the enterprise. This kind of mistake might result in the company making the front page because critical data was stolen, lost or leaked. Nothing you want to happen to your employer. Architects of this kind don’t deliver solutions to technical problems, instead they are forcing additional requirements on the project.

If you are working for a large company you probably have both roles, but are the project members aware of the different roles? I wasn’t until recently and I think
this is really bad. In my opinion:

  • The roles should be clearly distinguished by very different titles, so nobody thinks these two are the same.
  • The two roles should be performed by different people, because a single person trying to perform both gets into some awkward conflict of interest: Should he stop a project that fails to implement a critical non-functional-requirement and thereby setting himself up as the architect who failed? I don’t think this works very well. More importantly: It fails especially when things get difficult and failure has the worst possible effects.

So how is this handled at your company? Is it handled at all?

Critical Skills for Software Developer too few People talk about

There are many discussions of what you should learn or need to know as a software developer. Most of the time these discussions are about technical stuff, like IDEs, programming languages, patterns, tools and so on. Of course there are also discussions about soft skills: How to give feedback, how to deal with difficult coworkers or customers. All important stuff.

But there is something in between. That’s what this article is about.

Take tiny steps: I spend a lot (read: too much) of my time on stackoverflow answering questions. And very often I find questions of people being completely lost in the mess they created. You can often tell simply from the tags they use. If they combine things like jsf, cdi and hibernate they obviously haven’t the slightest clue where even their problem is. They created 5 different files for 3 different frameworks and now something doesn’t work. Many very experienced developers will have a hard time setting up their preferred persistence framework, front end framework, build tool, DI-framework and what not in one go. So no surprise they failed. But how does a seasoned developer do this kind of thing? What is the advice?

Walk with tiny steps! Actually, at first don’t move at all. Think: What is the smallest possible change to the code base that can give you working code that is a little closer to your goal? If this involves changing more than 10 lines of code, keep thinking until you have a better idea.

Now make that step.

STOP! Look around. Did it work? If not you have at most 10 lines to worry about, ok I give you another 3 for possibly missing changes, but that’s it. And a tiny step never includes front end, back-end, and domain logic at the same time.

Understand stacktraces: This one comes again from stackoverflow questions. Actually from two kinds of questions. The one kind goes like this: “My code is broken, please help.” The other kind looks like this: “When I do x my application fails with this error message:

Application failed with XNotSupportedException in line 11, do y instead.

Yupp: the first kind didn’t even realize that a call stack might be important, the other kind didn’t bother to read it. I know error message can be intimidating and hard to understand. But a lot of work goes into these things and for a good reason: Learn to read them. You need to understand every single line of a stacktrace. If you have problems with a line, there is probably a stackoverflow question about it. Find it and read it.

Create and test theories: Developing software is an art. But it also has a lot of scientific work to it. And science works like this: You make an educated guess about something, and then you cook up an experiment to test it. (This is how Feynman defined it, and if you don’t know Feynman you should fix that too.)

The art part is back in the game when it comes to creating good theories. Good theories are easy to test. If you need a week to test a theory, you might want to test other theories first.

Good theories have a good chance of being true and of being false. A theory that is false with high probability is just a stupid idea and a theory that is certainly true is also known as a fact we already know. Everything in between allows us to learn about the problem at hand.

The term “Theory” might sound scary and complicated but it is actually rather easy. Let me give you an example. Your application doesn’t have an effect you are expecting. You inspect the code involved where a method gets called which should cause the effect. An obvious theory would be: “That method never gets called”, Another one, kind of the opposite: “The method does not cause the effect” a third one might be: “The effect does happen, but you fail to observe it due to some other problem”. If you like me a couple of years ago you don’t even think about this kind of stuff, because it seems so obvious and natural, but trust me: I have seen people randomly editing code trying to fix bugs with some kind of simulated evolution: apply random changes until the chances of survival increase. It seems like these developers forget that evolution involves as an essential part the death of millions of specimen …

Ask good questions: I consider the previous three points to be a precondition for being able to ask good questions. If you need more tips, go here.

Abstract: This one might be the one most difficult. At least it is difficult to teach. Software development is about abstracting over things. A small child can add two specific numbers, using their fingers. Describing the algorithm they use without reference to specific numbers is programming (and a little more difficult).

I consider my time as a physics student an excellent training for this. Boy was it abstract at times. Sometimes it was so abstract, we literally didn’t know what we were talking about. But you can hardly expect people to study physics just for this. One thing that might help is learn different languages, because different language can easily abstract over different things. Learning this different ways to abstract over stuff will help you to abstract over your next problem in a meaningful way. Oh, and if a coworker keeps replacing pages of your code with 5 lines of her code, you know whom to ask for mentoring.

Be Curious: We all have copied code from we found using our preferred search engine. That is OK. In some cases it is even OK to use the code without really understanding it. But when you use the same kind of construct over and over again you must stop and ask yourself: Oh is this sh*t working? This applies in all directions: Those weird JPA annotations, that fancy Javascript module pattern, the garbage collector, a compiler. Of course as you move further from your domain your understanding will be more superficial and more limited. Most of us Java Developers hardly know anything about how CPUs actually work and that is ok. But that mocking framework you use every day, I’m absolutely convinced that at least in principle you should be able to recreate it. And it is not that difficult. Just pick every day or at least every week, one thing that you use regularly and look up how it works.

How to Create a Legacy Code Kata Source Code

From time to time I do a Clean Code Workshop for coworkers or customers. A large part of these workshops deals with legacy code. I always start with the Ugly Trivia Game by J. B. Rainsberger, which actually isn’t by him, but I use his version anyway. While it is a great resource it gets boring after you have reviewed, tested, refactored, tested it some more and reviewed the tests and refactorings. Also: does it really look like the average legacy code we find in our projects? I don’t think so. Real life legacy code has more dependencies and does more really stupid stuff. My favorite so far was a class that loaded stuff from the database in the constructor. Not fun.

Therefor I like to create a little code base for working with legacy code that is very realistic but still small enough so one can handle it in the setting of a workshop and it is actually really simple to do that:

First pick some class that is ugly. Big methods are great. Sometimes you come a cross classes that are super tangled with 2-5 other classes. Those are super awesome. Don’t pick anything to large. A class with 5000 lines just create more work, not more learning opportunities.

Second copy that class (or that small class cluster) in a new project. No dependencies, none of the other stuff it works with. Most likely it wont compile, we gonna fix that in the next step.

Third fix all the compile problems using one of the following approaches:

  • Just add simple libraries like logging or Apache commons to the project.
  • Create missing classes using your IDE, will all the right methods. If the methods look like getter and setter, actually make them getter and setter.
  • If the methods look more complicated just throw a SomethingTerribleIsHappeningHere exception.

This is really fast, works with 98% of all legacy code I came across so far and creates some mean challenges for working with legacy code.

Softwaredevelopment, Learning, Qualitymanagement and all things "schauderhaft"