What this book covers
Chapter 1, The Essence of Software Architecture, revisits the importance of software architecture and the role of software architects in an organization. It covers how the structure of an organization affects architectural decisions. Then it discusses choosing a framework and the factors to consider in the process. Several industry-standard documents and diagrams are introduced, which will be used for illustrations in subsequent chapters.
Chapter 2, Principles of Software Architecture, explores multiple ways to visualize and quantify software architectures, extracting quality attributes for measurement and analysis. It then delves into three key concepts: the separation of concerns, cohesiveness, and coupling. Popular architecture principles such as SOLID, the Law of Demeter, YAGNI, and future-proofing are also covered. These principles lay the foundation for further exploration of architecture styles in the following chapters.
Chapter 3, Polymorphism and Alternatives, uses a real-life problem and solves it using multiple styles in Kotlin code. It starts with a polymorphic solution, then explores two solutions involving Kotlin sealed classes. Next, a solution using delegation is presented, followed by a functional approach. Finally, all approaches are compared based on system quality attributes.
Chapter 4, Peer-to-Peer and Client-Server Architecture, focuses on network communication in distributed systems. It includes a step-by-step guide to implementing a client-server solution with an API-first approach using OpenAPI specifications and the Http4K framework in Kotlin. The chapter then implements a peer-to-peer solution to the same problem and compares the two approaches, discussing which is suitable for different situations.
Chapter 5, Exploring MVC, MVP, and MVVM, shifts focus to frontend applications. Using a sample Android application, we apply MVC, MVP, and MVVM to observe the evolution of the implementation with different architecture styles. The three patterns are compared along with other commonly used styles.
Chapter 6, Microservices, Serverless, and Microfrontends, moves the focus to the backend. This chapter shows how monolithic applications and service-oriented architectures evolve into microservices and nanoservices. It explains how serverless architectures impact modern software systems through cloud provider services. Finally, the frontend counterpart of microservices, the micro-frontend, is discussed.
Chapter 7, Modular and Layered Architectures, starts with three layered architectures—Clean architecture, Hexagonal architecture, and Functional Core Imperative Shell—that have similarities and differences. They are demonstrated and compared using Kotlin code for the same real-life problem. Later, the chapter explores the Connect pattern, providing a modular approach to integrate with remote systems.
Chapter 8, Domain-Driven Design (DDD), takes a deep dive into DDD design activities. It starts with basic concepts and terms, then looks at the bigger picture of the domain with Strategic Design. A bounded context is selected for Tactical Design. The chapter also walks through three popular domain modeling activities with a real-life example.
Chapter 9, Event Sourcing and CQRS, extends the DDD practices from the previous chapter into two powerful architecture patterns. It first illustrates the use of Event Sourcing with a real-life example, then explains how CQRS can be applied. Finally, it combines Event Sourcing and CQRS as a solution to the same problem to unlock the potential of both architecture styles.
Chapter 10, Idempotency, Replication, and Recovery Models, discusses three related architectural concepts. It starts with idempotency in distributed systems, providing practical examples of how to implement it. Next, several replication models are explored and compared using the CAP Theorem. The chapter concludes with system recovery, using RAFT leader election as a case study.
Chapter 11, Auditing and Monitoring Models, demonstrates a sample audit trail structure in Kotlin that can be used by multiple services but centrally recorded. It also discusses various monitoring data formats and approaches for collecting data for monitoring purposes. The chapter covers structural and contextual logging with Kotlin code, as well as automated alerts, incident management, and metrics.
Chapter 12, Performance and Scalability, focuses on measuring performance using defined metrics. It showcases performance testing through basic approaches and micro-benchmarking. The chapter guides you through performance testing workflows while discussing strategies for performance improvement using Kotlin code. Additionally, a voting system is used to illustrate the process of enhancing performance and scaling the system.
Chapter 13, Testing, explores the role of Quality Assurance. It examines various testing methods within the Testing Pyramid and highlights best practices for each type. The chapter includes a step-by-step journey through a Test-Driven Development exercise with the Kotest framework.
Chapter 14, Security, focuses on safeguarding software systems and their data from malicious attacks. It starts with securing network communication using Transport Layer Security (TLS). Then, the chapter covers Multi-Factor Authentication (MFA) for user identity verification. It also addresses common methods of authorization and data entitlement, techniques for hiding and anonymizing sensitive data, and various network security approaches. The chapter concludes with a discussion of DevSecOps and a Threat Modeling exercise.
Chapter 15, Beyond Architecture, covers various engineering topics beyond software architecture. First, it explores several Kotlin language features that help engineers achieve better code quality and software architecture. Next, it discusses the transition from Java to Kotlin with the help of IDE features. The chapter compares two CI approaches: feature-based and trunk-based development. It then covers release strategies, briefly touches on Developer Experience, and concludes with a look at current trends in software architecture.