Introducing Interaction-Driven Design
Introducing Interaction-Driven Design
IDD is an iterative approach to software design and development, which focuses on modeling behavior according to the external usage of the system.
Join the DZone community and get the full member experience.Join For Free
TL;DR: IDD is an iterative approach to software design and development based on Outside-In Development which focuses on modeling behavior according to the external usage of the system while maintaining an internal representation of cohesive business components.
Before reading this post, I strongly recommend you read the two previous blog posts that serve as a foundation to this blog: MVC, Delivery Mechanism and Domain Model and A Case for Outside-In Development.
Most software projects become very difficult to maintain and evolve after a period of time. Business is constantly complaining that things take forever to be delivered. Developers complain the code is a mess and that they struggle to understand it. They say the code is poorly designed, not reflecting business concepts and respective flows. More often than not, they wrote the code themselves.
Development teams don't normally have an efficient way to slice business features and design software in a way they can deliver software incrementally while keeping the codebase aligned to the business flows and easy to maintain.
A good software design process should help developers to clearly represent functional areas and business flows in their applications, aligning the changes in the business with their respective software components. A change in one area of the business should not cause multiple areas of the system to be changed. Identifying behavior in the system should be straightforward and new developers should not have any problems to understand the code.
Interaction-Driven Design (IDD)
IDD is an iterative approach to software design and development based on Outside-In Development which focuses on modeling behavior according to the external usage of the system while maintaining an internal representation of cohesive business components.
IDD's premise is that an application should only exist to satisfy the external needs of users or services - called actors. Each interaction between an actor and the application represents a need of the actor that has to be fulfilled by the application. The goal of IDD is to iteratively design and build applications that satisfy those needs.
Building on top of a solid software design foundation, IDD was inspired by ideas from Responsibility-Driven Design, Domain-Driven Design, Behaviour-Driven Development, and many other design principles, patterns, methodologies, and approaches already available.
IDD puts together a cohesive set of new and existing methods to create a more prescriptive, but flexible, approach to software design and development.
IDD focuses on the design and development of the functional aspects of a system, including architecture, and macro and micro design.
IDD Approach Summary
IDD focus on the interactions between actors and the application, and between the different behaviors inside the application. Internal behavior is discovered by decomposing behavior triggered by actors. The process is repeated for each behavior identified, breaking them down into smaller behaviors until there is no smaller behavior. Coarse-grain behaviors become clients for fine-grain behaviors. Each behavior is created to satisfy the needs of an existing behavior or external need. This is what we call outside-in design.
Behavior discovery happens at five levels: cross-application feature, application, application feature, component, and unit.
- Cross-Application Feature: Behaviour provided by a group of applications, normally in a distributed (micro)service architecture.
- Application: Collection of behaviors provided by a single application to external actors. Each behavior provided to the external world is considered a feature.
- Application Feature: Behaviour that satisfies a single need of an actor. Often a feature orchestrates the behavior of different components (or functional areas).
- Component: Collection of behavior related to a single functional area.
- Unit: Non-decomposable behaviour, part of a component.
The term functional area is used to define an area of our business domain. Examples of functional areas would be things like products, payments, customers, or orders. Depending on the size, complexity and architecture style used, functional areas may be mapped to independent applications (services) or business components inside a single application.
Outside-in Behavior Discovery
Regardless of the level, behavior discovery is mostly done outside-in. The only difference is the level of abstraction used.
For a Cross-Application Feature in a microservices environment, we would first choose a few major flows (user journeys, business flows) triggered by actors. For each one of the flows, we do the following:
- Define the application (service) that will handle the actor's request. This is the application that will "own" the cross-application feature.
- We then decompose the main behavior into smaller behaviors, making sure they are all at a similar level of abstraction.
- Next step is to define which functional areas will own the smaller behaviors found.
- If a suitable functional area already exists, the behavior is added to it. If not, we need to create one as there is probably a domain concept missing in our domain.
- Repeat the process for each smaller behavior until we cannot decompose more, or we arrive at a level of abstraction that is not relevant.
This process should be done collaboratively with the whole team, including product owners and testers. The best way to represent this discovery process is drawing sequence diagrams on a whiteboard. The functional areas discovered after exploring a few major flows can be consolidated and will become natural candidates to become independent applications (or services).
The same process described above can be used for behaviors at lower levels, like components. The difference is that instead of talking about high-level behavior, functional areas, and services, we would be talking about low-level behavior, classes, and methods.
More details about behavior discovery at different levels in separate posts.
IDD Iterative Development
IDD advises that a software team should work on a single theme of work (epic) at a time. This minimizes dependencies between teams, keeps a team focused on delivery, and keeps the design of different areas of the application stable and consistent.
Each theme of work is broken down into features, which are prioritized on the team's backlog. The team works in an iterative manner, one feature at a time. Each feature is divided into vertical slices, from the delivery mechanism all the way to persistence or integration with other applications. Simple features have a single slice where complex features might be divided into many slices. The team works on one slice at a time and only moves to the next once the slice is deployed into production.
Before committing to a feature, the team must understand how actors will be interacting with the application in order to benefit from the feature. A horizontal exploration of the delivery mechanism must be done before dividing a feature into small vertical slices. Feature slicing should be done from the outside to the inside, in other words, from the delivery mechanism to the persistence or integration points.
Different strategies for slicing features will be described in future posts.
IDD Development Process and Prioritization
When building software using IDD, the first step is to identify the actors (users or other systems or services) that will benefit from the features of our application. Each feature should address the needs of one or more actors.
Once we identify the actors, we analyze the interactions the actor will have with the system. In this analysis, we do not go deeper into the internal behavior of the application. We keep it superficial, purely focusing on the conversation between the actor and the application. Each interaction between the actor and the application is a feature. We call this step horizontal exploration.
With a list of features at hand, we prioritize them and vertically slice the highest priority feature.
Each slice is developed outside-in, starting from the delivery mechanism (user interface, inbound queue, API endpoint, controller, etc.) and moving inside gradually until the whole slice is implemented.
IDD Design and Test Direction
In IDD, we start designing and testing from the input (outside) to the output (inside), following the external needs of users or other systems.
IDD aligns design and test-driven development (TDD) to the execution flow.
IDD is an outside-in software design methodology that helps development teams to design and build software based on the interaction of actors with the application and the behaviors within the application.
IDD promotes iterative development and tight collaboration between developers and the business unit. Sustainable evolution of the software and continuous delivery are some of the main goals of IDD and both are achieved via a strong focus on the design of the application and splitting the work into small vertical slices.
In future posts, I'll be describing, in far more detail, all the elements within IDD including requirements gathering, architecture, testing, code organization, requirements slicing, and much more. In the meantime, you can watch a presentation that focuses on the more technical side of IDD.
Published at DZone with permission of Sandro Mancuso , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.