When designing and writing documentation for a project an architecture needs to be clearly defined: what are the high-level modules of the system, what are their responsibilities, how do they communicate with each other, what protocols are used etc. But in this list, should the concrete technologies be specified or this is actually an implementation detail and need to be specified at a lower level?

For example, consider a distributed application that has two modules which communicate asynchronously via AMQP protocol, mediated by a message broker. The fact that these modules use the Spring AMQP library for sending and receiving messages is a fact that needs to be specified in the architecture or is a lower-level detailed design/implementation detail?

4 Answers
4

As a software architect, you will have to make decisions what components/technologies are essential for your architecture, and which are "implementation details". For example

is a specific database system part of the high-level architecture? For some applications this may be true, for others it is important to keep the programs independent from the database vendor. Tools like ORMs can help you here, but then you may have to make the architectural decision of choosing a specific ORM.

are the programming language(s) for your system part of the high-level architecture? Well, in most cases you cannot easily switch the language afterwards when you have already written several thousand lines of code, so this will be normally a high-level architectural decision. Of course, I know examples where libraries are written in a DSL and automatically translated into different programming languages, but that is not the typical case.

should the use of Spring AMQP part of your architecture or an implementation detail? Well, AFAIK AMQP is a standard protocol, and there exist different implementations / libraries supporting it. If you want to keep the option of changing the AMQP library later, you probably want it to be declared as an implementation detail.

In fact, some technologies are easier to be kept "as an implementation detail" as others, and it is often a trade-off between higher flexibility and an increased development effort where to draw the line.

Under this definition, it's easier to characterize architecture by looking backwards on an existing system than by looking forwards while the system is being designed. It can still be used during design, IMO. You could say that a technology choice can be considered architectural when you have designed large parts of the system in such a way that they are tightly coupled to your technology. (For example, choice of programming language is extremely likely to be an architectural decision.)

There are clearly architectural technologies that go directly in an architecture documentation, like CORBA or .NET or a MessageQueue.

If you can have an abstract form of it, e.g. only the interface that multiple implementations support, keep it at the abstract level. If you have it, specify those in the implementation documentation. If you do not have an implementation documentation,
you can specify it in the overall architecture.

On the other hand, there are technologies that probably never go into an architecture documentation, like a certain JSON parser or that like.

On very complex systems, you would have a system specification anyways, which is
more of an overall architecture.