Agile Component Design

2020 04 01 head

You are an experienced programmer. You master your primary technology stack and systematically write clean code.

Your team recognized your merits and asked you to take ownership of whole packages in the application.

You are now responsible for creating or modifying a software component in your current application.

This is a design activity.

How can you create a good, legible, maintainable component architecture?

How can you validate your functional and non-functional requirements?

Yes, you are right. You are responsible for architecture decisions at component or subsystem level.

Below a set of tools to improve the quality of your design.

Design Approaches

Patterns and Idioms

The pattern movement was started last millennium. Very talented and experienced developers have documented how to solve common problems elegantly and effectively. Depending on the programming language, you are using different idioms are preferred.

The way to solve the same problem is different in Java, Scala, C++, Python or C#.

You should know all regular structural, behavioral and creational patterns [1]. Explore your programming language and discover how idioms and patterns have evolved between major releases. For example, lambda expressions and streams introduced in Java 8 - released Spring 2014 - completely transform the solution for regular business logic.

Records introduced in Java 14 - released Spring 2020 - have a huge impact on how your architecture deals with data transfer objects – DTO – and immutability [1].

Read Open Source Code

Stop inventing the wheel again and again. Avoid Not Invented Here syndrome. Your current problem was already solved multiple times. Explore open source solutions, read posts, study books. Select the most adequate solution and fill free to adapt and improve it.

Instead of searching for a solution for days, post your question on an adequate forum or on Stack Overflow. Fill free to improve the suggested solutions.

Become more efficient and use the wisdom of all these developers accessible through the Internet. Always verify the quality and adequacy of their proposed solutions.

Java Standard API

Know your programming language and the huge associated standard libraries part of your technology stack. Wisdom is coded in this code. Standard patterns are implemented in almost all packages. Idioms are encoded everywhere.

See how Java deals with human and machine time with java.time package. Decades of trials and errors were needed to finally create a balanced and simple to use time abstractions. The author of Joda Time experimented years before he wrote the java time package – JSR 310 – introduced in Java 8. All these decisions and learning are encoded in this code.

Clean Architecture

Clean Code

You want to create a clean architecture [2] you are proud of. You must first write a clean code [3]. Clean architecture build up on clean code. Promote clean code in your agile team. Agile code is clean code.

Modern integrated development environments IDE provide static code analysis tools to detect smells in your source code. SonarLint is available for all major integrated development environments.

Use these tools to steadily improve the quality of your code and remove well-known smells.

Do not fall to the fallacy to draw beautiful and useless UML diagram and write thick Software Architecture Design documents.

The real architecture is hidden in the source code of your product. You still document all major Architectural Decisions.

Know Your Programming Language

If you are developing in Java, you should use the current features of the programming language. For example, with Java 14, you have access to:

  • Try with resources and closeable resources. This construct is an implementation of automatic resource management.

  • Immutable collections.

  • Streams, optionals, filters, and collectors.

  • Predicates and functions to define lambda expressions.

  • Records and immutability for objects.

  • Pattern matching syntactic sugar as for instanceof operator.

  • Switch expressions and not only switch statements.

  • Text blocks to write legible multi-line text expression.

Aggressive Refactoring

The entropy of the source code increases over time. Only continuous and aggressive refactoring mitigates the degenerescence of your application [4, 5, 6, 7]. Each time you correct an error or add a new functionality refactor your code. Remove smells, compiler warnings and migrate older code to use newer and better features of your programming language.

Acceptance Test Driven Development

Your users want a working application. Write acceptance tests insuring all relevant functions are tested through your continuous integration pipeline. You guarantee your users the application behaves as specified.

Test Driven Development

Testability and changeability of your application are architectural aspects. You must have a way to verify these non-functional requirements. Test driven development is a proven approach to fulfill these requirements and validate them continuously.

Continuous Integration

Continuous integration and delivery are the mechanisms to continuously validate and verify all functional and non-functional requirements are correctly implemented [8]. You guarantee your users and customers that any software delivery they get is compliant and correct.

Each time you find a discrepancy, add a test validating the requirement behind this fault. The same error will never happen again.

Good Practices

Publish your components on a central repository such as Maven Central. Your users have easy and standardized access to your components and their latest version.

Build tools such as Gradle Build Tool and Maven or IDE such as IntelliJ IDEA allows potential users to fetch the component without having to install out-of-the-box mechanisms.

Javadoc is the standard and hugely helpful approach to document classes and component public interfaces in Java. Similar tools exist for other programming languages.

Architecture design records provide hints why specific design decisions were chosen. Your users can better understand the path you follow and the selected tradeoffs of your design. They do not have to agree, but they can understand the arguments why you choose so.

Static code generator is an actual good practice to provide the current documentation and tutorials for your components. We write all our documentation in the Asciidoc format - including plantUML and highlighted source code - and generate our website using Hugo tool suite.

Start small and improve your approach every day.

Agile Architecture Series

The agile architecture track contains the following blogs

We also published our agile architecture course (3 ECTS) used for teaching computer science students at bachelor level at Swiss technical universities.

References

[1] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns. Addison-Wesley Professional, 1995 [Online]. Available: https://www.amazon.com/dp/B000SEIBB8

[2] R. C. Martin, Clean Architecture. Pearson, 2017 [Online]. Available: https://www.amazon.com/dp/0134494164

[3] R. C. Martin, Clean Code. Prentice Hall, 2009 [Online]. Available: https://www.amazon.com/dp/0132350882

[4] M. Fowler, Refactoring, First. Addision-Wesley, 1999 [Online]. Available: https://www.amazon.com/dp/B004PQQRK2

[5] M. Fowler, Refactoring, Second. Addision-Wesley, 2018 [Online]. Available: https://www.amazon.com/dp/0134757599

[6] J. Kerievsky, Refactoring to Patterns. Addison-Wesley Professional, 2004 [Online]. Available: https://www.amazon.com/dp/0321213351

[7] M. C. Feathers, Working Effectively with Legacy Code. Prentice Hall, 2004 [Online]. Available: https://www.amazon.com/dp/0131177052

[8] D. Farley, Continuous Delivery Pipelines. 2021 [Online]. Available: https://www.amazon.com/dp/B096YGZVZ9


1. Java 17 LTS added full support for algebraic data types. with the record and sealed concepts.