Notation, Notation, Notation

Simon Brown -inventor of the C4 model – recently came up with a checklist about diagrams and notations.

A few people have asked me for this recently so … if you’re looking for my software architecture diagram notation checklist, you can find it here…

Software Architecture Diagram Review Checklist

Although it seems obvious what is checked in this list, almost every single diagram I have encountered in my career did not provide all the information. Copy it, print it, as an architect (and software developer) carry it with you – and use it.

Link: https://c4model.com/assets/software-architecture-diagram-review-checklist.pdf

Semantic Versioning

In my current team (actually the whole company) we end up within the dependency hell day by day. Not only that many teams just don’t do any versioning, if they do there are no clear rules how they should do.

Semantik Versioning specification provides a great introduction of how and when to use (semantic) versioning. Definitely worth a read.

In the world of software management there exists a dreaded place called “dependency hell.” The bigger your system grows and the more packages you integrate into your software, the more likely you are to find yourself, one day, in this pit of despair.

In systems with many dependencies, releasing new package versions can quickly become a nightmare. If the dependency specifications are too tight, you are in danger of version lock (the inability to upgrade a package without having to release new versions of every dependent package). If dependencies are specified too loosely, you will inevitably be bitten by version promiscuity (assuming compatibility with more future versions than is reasonable). Dependency hell is where you are when version lock and/or version promiscuity prevent you from easily and safely moving your project forward.

Link: https://semver.org/

Pro Git Kindle Edition

Just in case you own a Amazon Kindle an you are working a lot with Git. And just in case you struggle with Git the same kind as I do e.g. when it comes to a rebase, have a look at Pro Git. It’s available as Kindle edition for free at the moment from amazon.de.

progit

Although the book is from 2014, it still covers many of these daily things that are beyond a simple push or commit when using Git. Should be in every developer’s book shelf.

Geeks in Teams – Team Geek by Fitzpatrick and Collins-Sussman

teamgeekSome weeks ago, I came across a quite interesting title from O’Reilly Media, Team Geek by Brian W. Fitzpatrick and Ben Collins-Sussman. There are quite a lot of books out in the shelves trying to explain how to behave as well as how to improve your life as a professional programmer. However, most of them are either hard to read, difficult to understand or just boring while repeating stereotypes over and over.

Team Geek is quite different, though. It seems the book benefits from the experience of the authors. Both come up with a bunch of experience working at Google and probably dealing with quite a lot of people during their professional life.

The Content

Six chapters, each about 20 pages – some with topics you probably never thought about and others just confirming what you ever thought of but never believed in. And that’s basically what you most benefit from. The book shows you are not alone with your thoughts how teams and collaboration should work. It’s about you as a developer (as a human thing) but also working in a team of geeks (often not understood as humans at all).

The Truth

Based on my very own experience during my professional life, I have to acknowledge almost everything the two authors write is true. Considering the fact, the book is written based on an US American context, with different culture, people and background, most of the topics are true for European developers as well. It seems the kind of human becoming a developer is the same all over the world. Whatever if it was during my time in UK or Germany, the you can apply many of the patterns provided in the book to your daily job.

The Reader

Professional developers, managers, team leads, architects, open source developers and even designers could benefit from the book. However, I would definitely recommend to already provide some experience in this kind of business to fully understand (i.e. to feel with the authors) what’s written and to benefit from the book. Not sure if beginners (e.g. students) or juniors can benefit from the book. Eventually, the reader will find some hints how to improve his or her daily life within a world of geeks and nerds and how to strengthen the very own standing within the company or group.

Pros

  • well written and easy to read
  • chapters of the right size to read during an evening
  • nice illustrations (not a reason to buy but really nice to look at)
  • great content
  • references for further reading given

Cons

  • terrible to useless index
  • not suitable for juniors and beginners (but that’s fine)

Where From

You can order the paperback or the Kindle version from Amazon or get the entire set of digital formats directly from O’Reilly.

The Role of an Architect in Scrum

Over the last few days I (re-)thought a lot of the role of an architect in a Scrum team. I tried to avoid to read about other opinions and just thought of my very own experience over the last few years in agile teams.

There should be an architect in your organization, however, he should not be part of the Scrum team itself. Scrum is about the development process in your organization or project and as such is it a required constraint for the architecture to develop.

The architect deals with non technical issues, so called facts of life, politics, organizational constraints, budget restrictions and so on. No team member could address thees in the regular development sprints.

As an architect one should analysis and manage risks – again nothing a team member could do during a regular two or four week sprint. Considering risks probably begins long before the team is Assembled and t he project is started. In fact, as an architect one could even point out the project might not doable due to various reasons.

An architect has to run in iterative cycles as constraints change, customers come up with new and modified requirements and organizational goals mit shift over time. All this might require some redesign or evolution of the architecture. However, these architectural cycles are not bound to the development cycles of e team. They are more related to the business, customers and organization.

The architect is a technical leader. Maybe by prototypes or bullet tracing he shows how hard parts of the system can or will be addressed. As such he provides a base to the team to better estimate the complexity of the upcoming implementation. Eventually, as architect it is important to address the hardest issues first whiled the Scrum team addresses the tasks with the highest business value first.

As an architect you teach and coach your team. In Martin Fowler's article Who Needs an Architect?, published in IEEE Software, Fowler points out, that an good architect mentors his team, not sitting in his ebony tower.

Dealing with uncertainty is probably one of the most underestimated aspects of the dayjob of an architect. In the role of an architect, I have to make decisions under a high degree of uncertainty. As many aspects of a project change over time, early decisions are uncertain. However, as an architect, you have to consider the consequences of these decisions. It's a major part of your job to consider risks and work on plans wether any event occures that affects your project both, a a threat or a chance.

I contrast, in the role of an developer, you should not be confronted with uncertainty. You have a tough schedule and proper tasks to fulfill, Technologie and tools are in place and in the best case you have all the knowledge to perfomreyou task. If the requirements for your task are not clear, you probably cannot fulfill it.

I have experienced this very issue during the last few years several times. Most of the time this was caused by the lack of an architect or the position of the architect was not dealing with the role of the architect in a proper way, most of the time writing code themselfs.

Therefore, do architects write code? This might be one of the most discussed topics for software engineering. Personally, I have experienced both, architects writing (productive) code all the time a well as architects never worked in product development. As an architect you probably should provide certain coding skills. Earning your street cred before becoming an architect is inevitable. You must be able to read, understand and improve the code. However, you have to delegate the actual task of building the code base to others. Nevertheless, you probably have to improve your coding skills permanently. Therefore, an erchitect must be able to write excellent code, however he should not write the bits delivers despite prototypes and tracer bullets.

As a fact, running an agile environment does not supersede an architect. Neither does it reduntize the overall product planing and designing process. The architect is not part of the Scrum team as he does not deliver within the Scrum team. He is in a position existing before the Scrum team is assembled, he leads the direction and can hold an consulting position for the team. However, the a architect is not part of the sprint plan and as he is not part of the Scrum team as such.

Futures Software Architectures

Looking at myself, I see how different I work nowadays with devices than almost 30 years ago. In the early days of personal computers you spend a lot of time in figuring out what you actually can do with your Commodore C64 or your very first 286 hardware while knowing each component's specification. Nowadays it is simply about the available software. Most of the users probably do even not know about any technical details of the device they are using beside if it is slow or fast.

If you look at professionals who use computers, they often use one specific application, which maybe is shut down only once at the end of the week. Personal users probably don't know that there are more applications on the computer than the web browser.

As computer professionals we tend to forget to think about the why others do use computers. We see the full potential of the latest programming language, the computing power, the maximum available bandwidth and all the fancy features we know about.

Tablets such as the iPad or the new Nexus are great for end users. Quite intuitive to use, and no need to worry about the hardware. Whatever users want to to, they simply have to find the right app. I fact, I use my iPad for many common tasks, even for writing, blogging and editing images the apps are meanwhile quite well done.

Specialized applications used by various professionals do not need a fully equipped personal computer. Ever looked at a doctor's place? In every surgery you might find a personal computer running often just one program. Or have a look at a common electronic it furniture megastore. Each information desk will probably has one personal computer running one program on it. Often, these programs are typically host applications where the client continually requests information from a server application

There is no reason to put a fully equipped computer in every room for a single application. Either a thin client or some lightweight tablet might the answer here. Either a web hosted application or a small application communicating with a server (e.g. In the cloud) might be a good solution.

Cloud Hosted App

As professional software architects and designers we should consider this while designing application even if stakeholders still request old fashioned desktop applications.

 

Clean Interface Inheritance

Recently, I had a interesting conversation about interface inheritance with one of my colleagues. Reason was a decision necessary how to implement basic behavior based on a set of interfaces for a number of classes. At first, I was not comfortable to  let one interface inherit from another. I was quite biased from the design of the code base I am currently working on.

Generally spoken, each class inherits from its very own interface. In addition the inheritance scheme of classes is reflected in the interface inheritance as seen in the example below. Why would one come up with such a design at all?

Complexe Interface Inheritance

To understand this design (it’s still a design) some more context is required. In the particular codebase a dependency injection container is used to resolve instances of a particular type. To do so a unique identifier is required. This could be a string but also an interface. E.g. the Microsoft Extensibility Framework (MEF) makes usage of interfaces for resolving. Using MEF it is quite easy to get a set of components implementing a particular interface (e.g. some kind of IPlugin interface).

The issue I’ve seen, there are only few common interfaces in the codebase . Instead of collecting all types of a particular interface, dedicated interfaces are used to resolve particular instances of types. However, by using interfaces this way, the focus is to identify types by their interfaces not using interfaces as contracts.

Back to the issue how to design the interface inheritance, we came up with two alternate approaches, both valid indeed, but with very different design goals.

Implementing or Inheriting interfaces

In the left hand approach two types inherit from the same base type implementing a particular interface. Both types also implement another interface, i.e. both types fulfill the same contract. In the right hand approach we see both types inheriting from the same interfaces as well. While at the end both approaches will end in the same a similar result, there is a significant difference in the semantic.

Based on both approaches, we came up with two possible solutions for a .NET implementation. While this might seem quite academic to you, there is quite a difference how one might use these types.

Inheriting Interfaces vs Implementing Interfaces

As in the example before, both approaches will end up in two classes implemented identically, however, both implementations show semantic differences best seen when considering the usage of these classes. In the left hand example one could iterate through a typed list of IAlgorithm calling a Dispose method required by the IDisposable interface. This implementation is obviously contravariant. Following the right hand scheme, you might still iterate through the list, however,  before accessing the Dispose method it is required to cast the concrete instance to IDisposable. While being still contravariant, it is not implicitly possible.

The question now, is to decide when to use the fist or the second approach. Interfaces inheriting from other interfaces is absolutely valid once you can answer the question if your type is some kind of with yes. In the given example each algorithm is an IDisposable. No exception, no excuse. Choosing the second approach you should be able to answer the question whether your type needs to fulfill a particular contract with yes. If only a few algorithms need to be fulfill the contract given by the IDisposable interface, and an algorithm is not a IDisposable by default, the second approach might be the right to choose. While each algorithm is still an IAlgorithm, only some of them could implement the IDisposable interface.

Maybe this seems obvious to you, however, I still see quite experienced developers having significant problems in choosing appropriate inheritance structures. From avoiding inheritance at all to the point of using the most complex inheritance structures you might have ever seen in your programmers life. There is no right or wrong but there might be a best solution suitable to your problem. So never hesitate questioning your current design looking for a better approach. 

The Cleaner Coder

The Clean CoderI recently finished the latest book from Robert C. Martin aka Uncle Bob, called The Clean Coder.
Once finished there are many pro and cons about this book. At the beginning I was quite skeptic about the book but at the end I am glad I’ve read it to the very end.

The books is neither a set of rules that make you a better software developer nor is it really provide a code of conduct to follow in your professional life. However, if you spend some time in this industry, you will have many déjà vu moments while reading this book.

Very positive (if you a frequent reader and being interested in the people behind the books) is the fact that you will learn a lot about Martin as a person. Each chapter is more or less a short essay about a past project or part of his former work, some experiences he made and the (not so surprisingly) conclusions he made. There are quite a few sentences that are worth to remember, sometimes things you thought of many times but have not found the right words to write it down. Also you might find some interesting anecdotes you might learn something from (or did you know where carriage return and new line come ‘/r/n’ from and why they vary on different operating systems?).

One very positive aspect is that he points out what a professional (software developer) is, how he should behave and what could do to be recognized as such. In our industry you are still recognized as some kind of nerd, a geek who codes 24h hours a day, does not sleep, consumes a lot of caffeine and plays video games which a lack of social skills. While some of these things might be true, one expects often that you work more than the regular time, you solve each and every problem without any failure and that you come up with miracles, wonders performing magic, voodoo and code kung-fu each and every day (often for a very conservative salary). Nothing you would expect from other professionals (lawyers, doctors etc.).

Eventually, he writes about many things I, and probably you too, experience each and every day in our day work. At the end it is a nice reading book you might read during some evenings. Just the very final chapter about the tools he uses in his work (vi, Emacs, Eclipse etc.) and the frequent mentioning of FitNesse (which is Martins’ project) are quite unnecessary.

I am not fully convinced that the book is a must have reading, however, I work in this industry for nearly 13 years in various projects, research and product development, large and small companies, consulting and academia with different teams in different countries. At the very end it is quite calming to see once more that my problems are everywhere the same, have been the same for a long time and probably will stay the same for a long time in this industry.

Clean Code: o = 0

I do necessarily  agree with all statements in Clean Code by Robert C. Martin. One of the sections I though is completely obsolete was a statement about disinformative names:

“A truly awful example of disinformative names would be the use of lower-case L or uppercase O as variable names, especially in combination. The problem, of course, is that they look almost entirely like the constants one and zero, respectively.”

The corresponding example he gives is the following:

int a = 1;
if (O == 1)
  a = 01;
else
  l = O1;

So far I though it is obvious not to write such code, however, I came across similar code these days.

for (int o = 0; o < args.NewItems.Count; o++)
{
 string s = args.NewItems[o].ToString();
 ...
}

What’s the problem here? The variable name o is used for a counter and initialized with 0. While this is already hard to read, o might indicate that we deal with an object here. So when having just a brief look over this code you might get the impression it iterates through a set of objects. This is further supported by the usage of the NewItems property here, as in .NET object references is quite commonly used to resolve e.g. a key/value pair within collections.

When using a counter variable without meaning one should use common names such as i or j that a commonly recognized as counter variables.

for (int i = 0; i < args.NewItems.Count; i++)
{
 string s = args.NewItems[i].ToString();
 ...
}

This is only a slight modification but already improves the readability of the code.

<pre>

int a = 1;
if (O == 1)
a = 01;
else
l = 01,

</pre>