• Work Breakdown Structure vs Backlog

    Lately people keep telling me that things that are common practice in agile projects are done in waterfall based processes as well. And you know what? Some are. But others aren’t and again others are completely missing. So lets make a loose series of articles about waterfall artifacts and practices compared to matching agile artifacts and practices.

  • New Version of Degraph

    Last week I produced a new release of Degraph! Yeah. Unfortunatly I did not fix the most pressing issue: You still can’t filter dependencies that you know are causing violations. :-/

  • 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”.

  • 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: How 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.

  • Checklists for the win!

    I recently read "The Checklist Manifesto" and boy was it a great read.

    First it was fun to read! Checklists sound like the manifestation of boring, right? How about a story of surgeon who takes care of a minor flesh wound, when the blood pressure of the patient suddenly drops to almost zero. Cutting the patient open the surgeon finds the body filled with blood! Now if checklists are deemed appropriate for avoiding stories like this, they suddenly aren't that boring anymore, right? And the book is full with stories like this. If you imagine stories that you read visually and can't look at blood, sorry, this book isn't for you. Everybody else: Go get and read it.

    Professionals of various kinds use checklists. Medical doctors, Pilots of course and many more. Yet many people claim they don't need checklists. They are smart enough to do the right things. Their job is too complicated to be pressed in simple checklists. Really? So the job of a pilot is somehow "simple"? Or that of a surgeon? Of course it isn't. But still there are many things that are actually rather simple. And it is rather difficult to not forget about those. That's when checklists help.

    Since I finished the book I established two checklists for myself:

    One checklist I go through every morning at work. It looks something like this (without the italics, those are just for you so you can make sense out of the few words) and is written on a post-it taped to my monitor:

    • Check mail. Yes I'm proud that sometimes I'm so focused that I don't check mail at all, so I need it on my checklist
    • Check calendar. To make sure I'm aware of all important appointments today
    • Check logs. Of all servers, so if there is a new problem, I learn about it.
    • Check Jenkins. Mail notification doesn't work, too much E-mails.
    • Fill out time sheet. In the morning I remember what I did yesterday and I can enter the time I started to work.

    The second checklist is for debugging problems with dependency injection. As much as I like the Springframework, from time to time it complains about being unable to instantiate a bean, because a dependency is missing, although the bean is right there in my IDE. For this I created a checklist that lists all the various possible reasons for this problem:

    • What exactly is the problem described in the stacktrace. No bean of matching type? Or no bean of matching name? Or more than one bean?
    • Is the bean that should get found in the correct source path I have a history of putting beans in test instead of main
    • Does the bean that should get found implement the correct interface? Here it is important to check the full name
    • Does it have the correct name?
    • Are the scopes compatible? I'm not sure if this will actually result in the same problem

    I store this one in Evernote and will pull it up when I get this kind of problem the next time.

    The first checklist already proved highly useful. The second has still to be tested. I just created it when I tried to fix just that kind of problem the last time.

    What checklists do you use?

    One last word: Of course as software developers we have an advantage. Many things that ask for a checklist can be implement as a program. So don't replace your automatic build with a checklist please.

  • Why I Won't Accept ANY Magic Number

    One of the first things I like to establish in a new project is the use of tools like Checkstyle and Findbugs in order to codify some code guidelines and to avoid bugs that can be determined by static code analysis.

    Sooner or later with these tools one stumbles over a case where people have the feeling it is going to far. One such case is the check for Magic Numbers of Checkstyle. It will warn about any use of numeric literals except -1, 0, 1 and 2 that aren't used to define a constant.

    Many developers have a problem with this check as one can see from the resulting code. I have seen code like this

    private static final int FOUR = 4;

    and also

    private static final int FOUR = 5;

    and my all time favorite (I'm not making this up!):

    firstname = rs.getString(1);
    lastname = rs.getString(2);
    city = rs.getString(2 + 1);
    zip = rs.getString(2 + 2);
    country = rs.getString(2 + 2 + 1);

    But there is a different case where the discussion comes up. It's with obvious constants like 100 for converting fractions into percent values or 1024 for conversion between bytes and kibibytes. Some argue these aren't magic numbers (or magic numbers but not as bad) because their meaning is obvious and they won't change.

    I disagree and will vote to make them constants any time. Here is why:

    1. The meaning is NOT obvious. What does value * 100 mean? Is a fraction converted to percent? Is a length measured in meters, converted to centimeters? Or something multiplied by a rough approximation of g*g with g being the gravitational acceleration on earth? Or maybe I'm multiplying something with the size of an array, that happens to be 100. Can't tell. A simple constant with a proper name will fix that.

    2. Ok, I do agree, many of these constants won't change. But the purpose of defining constants (or methods, or classes) is not (only) to enable later change, but to make reading, understanding and reasoning more easy. So the question if a value might change in the future is completely irrelevant.

    3. (This one is the argument that I'm missing in most of the discussions) I just don't want to think about it or have others think about it. I have seen dozens, probably hundreds of instances, where a properly named constant would have helped tremendously understanding a piece of code. And I have seen very few cases where it might have hurt readability and not a single one where it hurt badly. Therefore: just extract a constant and be done with it.

    Note: Just because it is a constant doesn't mean it has to be public, or even a class level field. If it is used only in a single method a local variable is just fine.

  • What I look for in frameworks

    In every project the discussion comes up over and over again: should we use framework X? or Y? or no framework at all? Even when you limit yourself to the frameworks for web development in the Java space the choices are so plentiful, nobody can know them all. So I need a quick way do identify which frameworks sound promising to me and which I keep for weekend projects.

    1. Stay away from the new kid on the block. While it might be fun to play with the coolest newest thing, I work on projects that have a life cycle of 10-30 years. I wouldn't want to support an application using some library that was cool between March and July in 1996. Therefore I try not to put that kind of burden on others.
    2. Do one thing and do it well. A bad example for this is Hibernate/JPA. It does (or tries to) provide all of the following

      • mapping between a relational and an object-oriented model
      • caching
      • change detection
      • caching
      • query dsl

      It is kind of ok for a framework or library to provide multiple services, if you can decide on each service separately if you want to use it or not. But if it controls to many aspects of your project, the chance that it doesn't do anything well gets huge. And you won't be able to exchange it easily, because now you have to replace half a dozen libraries at once.
    3. Method calls are cool. Annotations are ok. Byte code manipulation is scary. Code generation a reason to run for the hills. In the list only method calls can be abstracted over properly. All the other stuff tends to get in your way. Annotations are kind of harmless, but it is easy to get in situations where you have more annotations than actual code. Byte code manipulation starts to put some serious constraints on what you can do in your code. And code generation additional slows down your build process.
    4. Keep the fingers of my domain model. The domain model is really the important part of an application. I can change the persistence or the ui of an application, but if I have to rework the domain model, everything changes and I'm essential rewriting the application. Also I need all the flexibility the programming language of choice offers to design the domain model. I don't want to get restricted by some stupid framework that requires default constructors or getters and setters for all fields.
    5. Can we handle it? There are many things that sound really awesome, but they require a so different style of coding, that many developers will have a hard time tackling it. And just because I think I can handle it, doesn't necessarily mean I actually can. So better stay simple and old-fashioned.

  • The Latest Version of Degraph is Available for Download at Maven Central

    Degraph is my personal open source project for visualizing and testing package dependencies in JVM byte code. I released the latest version 0.1.1, so go grab it while it is hot.

    What's new

    This release in mainly a bug fixing release. So the important changes are two bug fixes. Degraph 0.1.0 missed a few dependencies to static methods, and through class valued annotations. So you absolutely should upgrade. I hope you don't use many static methods, so the first bug won't bite you as bad. The second one is actually quite annoying with certain frameworks. Spring for example uses lot's of annotations, including those that contain references to classes.

    Fortunately upgrading your tests will be easy, because degraph-check is now available through Maven Central, which makes using it really a no-brainer.

    Although this release is just a minor one, a tiny new feature slipped in almost by accident. And when I tried it at work it turned out to be extremely helpful: You can now instruct Degraph to create a graphml file for failed tests. Just provide a path using the printTo method. An example looks like this:

      test("Check identifies cycles in junit") {
    classpath.printTo("junitDependencyFailure.graphml").including("**.junit.**") should not be (violationFree)

    This allows for a relative quick workflow:

    • Write your test
    • Run the test
    • Open the resulting graphml file in yed
    • Modify code or test
    • Run the test
    • Reopen in yed
    • Repeat the previous three steps until done

    I found this tremendously helpful when fixing the problems that the bugfixes mentioned before surfaced.

    Give it a try and let me know about your experiences in the comments below, or in the issue tracker over at github.

  • Five Reasons Why You Should Keep Your Package Dependencies Cycle Free

    If you are so unlucky to work with me in a project, you will suffer from the rule that all package dependencies must be cycle free. I will not only require this, but I will also create a unit test ensuring it using Degraph. Here are the reasons why I think a cycle free package structure is beneficial for a project.

    1. Helpful abstractions: If you implement stuff without thinking to much about dependencies you end up with cyclic dependencies almost for sure. In order to break those cycles you often have to introduce new abstractions in the form of interfaces. These interfaces often turnout to create a cleaner abstraction of what is going on in the application than the direct dependency that was there before.

      For example consider two packages Something and Other that depend on each other. As it is described, there is no way to tell why they depend on each other. But in order to break one of the dependencies you might decide to introduce an interface. The name of that interface might include valuable additional information about the relationship of the two. Imagine the interface ends up being named SomethingDeletionListener and located in Somehting and implemented in Other. This already tells you something about the relationship of the two packages, doesn't it?

    2. Clean Orthogonal Package Structure: Whenever you organize something in a tree like structure you probably want an orthogonal structure in that tree. This means on all subbranches of a branch are elements of single categorization. A good example is Customer, Order, Wishlist a different, also good example is UserInterface, Persistence, Domain. These kinds of structures gives a clear indication where a class belongs. If you mix the two approaches you end up with something like Customer, Order, Persistence. In such a structure it is not at all clear where classes for the persistence of customers belong. The result is a mess, which typically results in cycles in the dependencies, since a question like should Customer depend on Persistence or the other way around doesn't even make sense.
    3. Enables reuse: Ever tried to reuse a package or even just a single class from a project that doesn't care about dependencies? I tried. In 9 out of 10 cases I had two choices: Either take the complete project (not really an option), or do some heavy refactoring of the class before it even compiles without all the other stuff in the project. On the other hand in projects where package dependencies form a nice directed acyclic graph, it is perfectly clear what has to go with the class. Also the stuff people are interested in reusing is typically close to the leaves of the graph and can be extracted on it's own or with very few dependencies.
    4. Enables partial rewrites: Sometimes an idea once considered great turns out to be a really bad one. Sometimes it is so bad, you want to redo it. Acyclic dependencies limit the amount of code affected by the change. With cyclic dependencies often the complete application is at least in danger of being affected.
    5. Independent deployment: On the other hand, sometimes ideas actually turn out to be great. Maybe so great that they get used so heavily, that you need to scale it up and deploy it on three additional servers on its own, to handle the heavy load. Good luck in splitting your application in two or more parts that can be deployed separately when you have tangles between the packages. With a cycle free structure, the places where you can cut should be rather obvious.