The term INVEST is an acronym for good User Stories
- Independent (of all others)
- Negotiable (not a specific contract for features)
- Valuable (to the business or the project)
- Estimable (to a good approximation)
- Small (so as to fit within an iteration)
- Testable (in principle, even if there isn't a test for it yet)
While this is one of those platitudes, it's also good practice, and in principle a good idea.
But for any Enterprise systems I've ever worked going on 40 years, the notion of Independent needs careful consideration. Independent of what? Independent of all other User Stories? That would mine all the User Stories are standalone pieces of software. That means the system architecture, the process flow, the data flow architecture components all how NO dependencies on other. No interconnections. No externalities with other systems, other components of the same system, or each other.
This makes no sense for any development project beyond a de minimis project. I'm currently working a Health Exchange system for a State. There is an existing system. We're updating that system with the current State and Federal guidelines. There are interfaces to IRS, CMS, Identity Proofing, credit checking and a variety of other external and internal services.
The notion that a User Story would be Independent of all other User Stories makes no sense since the Integrated system is a tightly coupled set of concurrent processes starting with the initial request for Health Insurance ending with the issuance of a Health Insurance policy ranging for a commercial policy to Medicare.
The interdependencies e well defined, so making a User Story Independent can take place only to the minimal level that a User Story is dependent of other User Stories for collected data, processing that data, and producing data to be collected and processed by other User Stories.
Data and Process Independence might be a goal, but even then the reality of a complex system like Health Insurance is simply not a set of Independent set of User Stories assembled into a system.
The key word here is System.
One of the tools we use to model the system is Design Structure Matrix
The Design Structure Matrix (DSM) method, was introduced by Steward in for task-based system modeling and initially used for planning issues. It has been widely used for modeling the relationship between product components, programs, people, and work activities. [50], [397] DSM relates entities with each other in ways schedules cannot, for example, the tasks that constitute a complete program. It can be used to identify appropriate teams, work groups, and a sequence of how the tasks can be arranged. Risk interaction within systems and subsystems, between functional and physical elements, can also be modeled with DSM.
A DSM is a square matrix, with labels on rows and columns corresponding to the number of elements in the system. Each cell in the matrix represents the directed dependency between the related elements of the system. The DSM allows self‒loops (an element is directly linked to itself). These self‒linked relationships appear in diagonal cells.
DSM models interacting risks in a graphical representation produce numerical simulations of the risk and impacts on the probability of program success. Consider a system with two elements, A and B. The interactions between these two elements can take three forms ‒ parallel, sequential, or coupled. The direction of influence from one element to another is captured by an arrow in place of a simple link.
The result is a directed graph ‒ a digraph like this, that model sequential, parallel and coupled process.
An example of a DSM Di-Graph is
Besides the process, software, and User Experience modeling of the interdependent components, Risk Management and most critically Risk Propagation can be modeled with DSM.
Traditional risk models cannot model loops. Actual risks contain loops. Actual software process flows contain loops. Enterprise Software process and data flows always contain loops.
Here's an actual DSM for a Software Intensive System of System showing the interdependencies of the components, and more importantly how risk propagates through these interdependencies.
Interdependencies and the risk that is propagated through this interdependencies in the above matrix can be shown as a graph
Independent is too simple for any Enterprise System
So when you hear an agile purest talking about the I in Invest, ask is there is any business process loops, interdependencies between systems compoenents, externalities.
No? The I in Invest is probably a good idea
Yes? The product or service you're producing will have interdependencies between components.
This always takes us back the coupling and cohesion discussion all of us who were Software Engineers in the 1980's
Coupling is an indication of the strength of interconnections between program units.
Highly coupled have program units dependent on each other. Loosely coupled are made up of units that are independent or almost independent.
Modules are independent if they can function completely without the presence of the other. Obviously, can't have modules completely independent of each other. Must interact so that can produce desired outputs. The more connections between modules, the more dependent they are in the sense that more info about one module is required to understand the other module.
Three factors:
- the number of interfaces
- the complexity of interfaces
- the type of info flow along interfaces.
We always want to minimize the number of interfaces between modules, minimize the complexity of each interface, and control the type of info flow. In general, modules tightly coupled if they use shared variables or if they exchange control info. Loose coupling if info held within a unit and interface with other units via parameter lists. Tight coupling if shared global data. If need only one field of a record, don't pass entire record. Keep interface as simple and small as possible.
Cohesion is the measure of how well module fits together. A cohesive component should implement a single logical function or single logical entity. All the parts should contribute to the implementation.
This might be the actual definition of Independent fro the User Story
Many levels of cohesion:
- Coincidental cohesion: the parts of a component are not related but simply bundled into a single component.
harder to understand and not reusable. - Logical association: similar functions such as input, error handling, etc. put together. Functions fall in same logical class. May pass a flag to determine which ones executed.
interface difficult to understand. Code for more than one function may be intertwined, leading to severe maintenance problems. Difficult to reuse - Temporal cohesion: all of the statements activated at a single time, such as startup or shut down, are brought together. Initialization, clean up.
Functions weakly related to one another, but more strongly related to functions in other modules so may need to change lots of modules when do maintenance. - Procedural cohesion: a single control sequence, e.g., a loop or sequence of decision statements. Often cuts across functional lines. May contain only part of a complete function or parts of several functions.
Functions still weakly connected, and again unlikely to be reusable in another product. - Communicational cohesion: operate on same input data or produce same output data. The component may be performing more than one function. Generally acceptable if alternate structures with higher cohesion cannot be easily identified.
still problems with reusability. - Sequential cohesion: output from one part serves as input for another part. May contain several functions or parts of different functions.
- Informational cohesion: performs a number of functions, each with its own entry point, with independent code for each function, all performed on the same data structure. Different than logical cohesion because functions not intertwined.
Functional cohesion: each part necessary for the execution of a single function. e.g., compute square root or sort the array.
Usually reusable in other contexts. Maintenance easier. - Type cohesion: modules that support a data abstraction.
And just as a reminder, all those interdependencies have random connections depending on the process flow, random uncertainties - reducible and irreducible - that create risk. In the presence of uncertainty, estimates is needed to make decisions. There is no way out of this for any non-trivial software development project
This information comes from the Paul G. Allen School of Computer Science Software Engineering Course