Generalized observation

As a general observation, it seems that when software architects try to solve general problems, they come up with horrible designs; when they solve specific problems, they come up with good designs.

Designs made without reference to a problem often become complex and not very fit for purpose when we’re solving specific problems. As a general rule, avoid generalizations.

Some examples:

  • An Enterprise Service Bus may create a big project and maintainable needs for something that turns out to be only a few simple integration points.
  • Splitting a system into generic reusable services may make it harder to understand and maintain
  • A generalized security role model may make be hard to understand while the only thing the system needed was an “is_admin?” toggle.
  • A complex role based (“can create payment”) security model may hide control of authorization from the developers, making it harder to implement the usually more important data based (“can access account number 5”) security model
  • A general model for workflow transition may make it harder to implement the specific workflow you need for a particular process. And it leads to endless discussions about the relationship between a workflow, a process and a process step.
  • Generalized test strategies are often vague and require a large number of test environments. In the end, it doesn’t contribute to increased quality.

In “No Silver Bullet”, Fred Brooks introduces the concepts of “essential complexity” and “accidental complexity.” The complexity from generalization is always “accidental” (that is: not inherently necessary). When you focus on solving the essential complexity (that is: the users’ problem) as efficiently as possible, you may found the complexity of your problem shrink by half or more.

Have you ever found yourself thinking, “what specific problem was I trying to solve again”? Then you’ve probably been down the dark road of generic thinking.

About Johannes Brodwall

Johannes is Principal Software Engineer in SopraSteria. In his spare time he likes to coach teams and developers on better coding, collaboration, planning and product understanding.
This entry was posted in Software Development. Bookmark the permalink.
  • FWIW, Brooks discusses this topic in a little more detail in his latest book, The Design of Design

  • KristianK

    Sound advice, but not only for architects, I think this is just as important for Joe Average Developer. Perhaps not in the ESB case, beyond asking why five times…

  • But on the other hand – I have seen a lot of “solutions” that win the battle and lose the war; alongside a mindless interpretation of YAGNI, a mindset avoiding abstractions and generality may be just as damaging as over-engineering…

  • eirikma

    I always do this. That’s why I’m not an architect. :-)

    The opposite mistake, which I’ve more than once heard people try to defend using the same arguments, is to also ignore general design principles such as keeping (integration) code idempotent or ACID-compliant. “Don’t generalize. All we need is to copy this stuff over here, infer that that the time and user must be the same on both sides and invoke the service. We get the remaining stuff from the cache. A background thread will do that so that we don’t have to wait.” “I’m not generalizing – I’m saving your ass the day one of the systems goes down or out of sync”.

  • Eirik and Lars both point out the danger of not abstracting enough. My original blog post may have been slightly off the target, using YAGNI to make simplistic design can be a danger.

    A more valid target for me to focus on, and maybe the subject of a future post is when architects design a solution that doesn’t relate to the business problem they are trying to solve. Being “general” in this sense means ignoring the problem your solve in favor of the books you’ve read on fancy technology.

    Being in danger of ignoring the business problem and creating a solution that solves the total set of problems isn’t really the same dimension. Thank you for pointing this out.

  • Good post.

    For some reason, it seems to be very hard to realize the misplaced technology focus you describe and take the appropriate action. Developers as a group are very technology focused, which takes attention away from the struggling architecture. If we try to fix the problem, we tend to have a look at the technology instead of the design.

    Have you ever met a developer who does not want to think about how his customer is going to make money? I have met several.

    I find this behaviour very interesting, but I still haven’t found a general way of modifying it. So far, my toolbox consists of getting the team to describe what they are going to make to me, and to try to create metrics that measure business value instead of technical gadgetry. If anyone has suggestions for good such metrics, I am all ears.

  • You have a great point about focusing on the customer needs, Geir. Personally, I find that the most useful question to ask myself, and other developers, is how the flesh-and-blood end user will perceive this. What is he or she trying to accomplish?

    Understanding how the customer makes money may give a better answer, but understanding the experience of the user is almost as valuable. And it’s a much easier exercise.