Where Has My Software Architecture Gone?
Where Has My Software Architecture Gone?
At Java Forum Nord 2015, Oliver Gierke showed why it is important to structure your application well in means of micro- and macro-architecture. Managing package dependencies is a relatively new concept, but is crucial for a clean architecture.
Join the DZone community and get the full member experience.Join For Free
The new Gartner Critical Capabilities report explains how APIs and microservices enable digital leaders to deliver better B2B, open banking and mobile projects.
This article is part of a series about Java Forum Nord 2015, a conference that took place in Hannover, Germany. Links to articles about other talks I visited there can be found below.
Oliver's talk was the last talk I visited at the conference and the topic is one of my main interests: software architecture. Like Stefan Tilkov does in his talk "Breaking the monolith", Oliver distinguishes between macro architecture, which is the architecture between systems, and micro architecture, which is what is going on in the "black boxes" that are the systems. The need for dependency management in the macro architecture, which are .jar-files for example, is known and solved, for example by Maven and OSGI. Lesser known and often neglected is the dependency management in the micro architecture, that is between packages and classes. These dependencies should be made explicit and visible, for example by using tools like Structure101. Having a clear micro architecture that connects small units of code to an understandable system enables the process of easy reading how a system works. Small units of code that have clear dependencies and relations to other small units of code mean small units of understanding. In other words, it's possible to understand those isolated regions of code. This is not the case without a clear dependency management, which is known as "spaghetti code". Also, the effects of changes are predictable because the relations between components are known.
Two concepts of structuring code are layers and slices. While layers are horizontal boundaries like presentation-, service- and data access layer, slices are vertical classifications like "account", "customer" or "core". Layers are known to most developers and well understood. Slices however are fairly new and hardly understood, although they map the business logic. As you can see, the slices "account" or "customer" can directly be understood by the product owner, whereas he most likely doesn't care about what is in the presentation- or service-layer. Because of technical reasons like having a database on one server and the user interface delivered to all clients, layers also have a right to exist. So what is most important are the relations / dependencies between layers (layer to layer) and slices (slice to slice).
So the question is: How can this architecture, which is the dependencies between layers and slices, be maintained in Java code? The key concept in Java is packages. Packages have to be arranged intelligently to support reading the structure of a system directly from the code. For example, having the packages web.core, service.core and repository.core enforces thinking in layers, because web, service and repository are layers. The "core"-logic is distributed to these three locations and hard to find in an IDE because the package tree has to be visited in three different places. An alternate approach is the arrangement in slices: core.web, core. service and core.repository states "The core is made up of three technical parts: web, service and repository". Also, in an IDE, the core-code can most likely be seen without scrolling the package tree. This so-called "slicing" of an application can help you navigate in your code faster.
Another important way of forming the architecture are modifiers of classes, attributes and methods. Often, classes and methods are always declared public, which is not the correct use of this modifier. In fact, public is the default setting in most IDEs, which is the reason why most developers declare their classes and methods this way. As Oliver put it: "Start with less packages and the least visibility possible". Only expose classes and methods when it is necessary. Another bad habit is the overhasty generation of getter and setter methods immediately after adding a new attribute. If every new attribute "automatically" gets a getter and a setter, why bother to make it private?
The correct hiding of information and slicing of an application enables to go from micro- to macro architecture because slicing is one preparation for microservices. More sources, including Oliver's sample code base, can be found on his slides.
Other Content of Java Forum Nord 2015
These are the talks I visited:
- Keynote by Adam Bien
- "Reflecting Software Architectures" by Stefan Zörner
- "Yes we scan - Software analysis with JQAssistant" by Dirk Mahler (blog post by Dirk Mahler himself)
- "Mastering legacy code in x simple steps" by Falk Sippach
- "Swimming upstream in the container revolution: Containerless Continuous Delivery" by Bert Jan Schrijver
- "Functional Programming in Java 8" by Nicole Rauch
- "Where has my software architecture gone?" by Oliver Gierke
Published at DZone with permission of Steven Schwenke . See the original article here.
Opinions expressed by DZone contributors are their own.