Flat And Independent
Assume that company ABC develops products for customers in domain XYZ as follows:
To remove the “development process” variable from further consideration in this post (because, thanks to consultants, it seems like everybody and their brother thinks process (traditional, Scrum, XP, LeSS, SAFE, Lean, etc.) is the maker or breaker of success), assume that all the teams use the same development process.
As the figure implies, each product is tailor-made for each customer. Since there are no inter-team dependencies and there is no hierarchy in the organizational structure, each team is an island unto itself and fully responsible for its own success or failure.
The tradeoff for this team independence is that the cost of development for company ABC may be higher than alternative strategies due to the duplication of work inherent in this Flat And Independent (FAIN) approach. For example, the above figure shows that components A and B are developed from scratch 3 times and component 2 is developed twice. What a waste of resources, no? However, assuming that components A and B only need to be developed once and reused across the board requires that component A is identical for all customers and component C is identical for customers 2 and 3. However, even though the products are targeted for the same domain this may not be true. The amount of overlapping functionality for a given component is dependent on the amount of overlap between the customer requirements applicable to that component:
If there is zero requirements overlap, or the amount of overlap is so small that it’s too expensive to gauge, then financing three separate component development efforts is more economically viable and schedule-friendly than trying to ferret out all overlaps and embracing the alternative, Hierarchical And Inter-Dependent (HAID) strategy…..
Hierarchical And Inter-Dependent
Now, assume that company DEF also develops products for customers in domain XYZ, but the org employs the HAID strategy as follows:
In this specific instantiation of the HAID (aka product line) approach:
- Core asset component B is developed once and reused three times
- Core asset components A and C are developed once and reused twice
Beside the obvious downside of core asset components D, E, and F being developed but not reused at all (violating YAGNI in this specific case when it actually applies), there is a less obvious but insidious inefficiency in the two layer hierarchical structure: the product teams are dependent on, and thus, at the mercy of the core assets team. The cost and schedule inefficiencies introduced by this hierarchical dependency can make the HAID approach less economically viable than the traditional, seemingly wasteful, FAIN approach. But wait! It’s worse than that. If you’ve been immersed in the HAID way of life for too long, like a fish in water that has no concept of what the hell water is, you may not even know that you’d be better off if you initially chose, or currently revert to, the FAIN strategy.
Inappropriate application of, or poor execution of, the HAID approach to product development reminds me of the classic framework dilemma in software development. You know the feeling. It’s when you break out into a cold sweat after you choose a development framework (or development process!) and you suddenly realize that you’ve handcuffed yourself into submission after it’s too late to reverse the decision. D’oh!
I guess the moral of this story is nothing new: “just because you changed strategies to become more effective doesn’t make it so.” Well, maybe there is no moral, but I had to end this post some-freakin’-how.
Given no information other than the fact that some numerical computations must be performed on each individual target track attribute within your code, which implementation would you choose for your internal processing? The binary, type-safe, candidate, or the text, type-unsafe, option? If you chose the type-unsafe option, then you’d impose a performance penalty on your code every time you needed to perform a computation on your tracks. You’d have to deserialize and extract the individual track attribute(s) before implementing the computations:
If your application is required to send/receive track messages over a “wire” between processing nodes, then you’d need to choose some sort of serialization/deserialization protocol along with an over-the-wire message format. Even if you were to choose a text format (JSON, XML) for the wire, be sure to deserialize the input as soon as possible and serialize on output as late as possible. Otherwise you’ll impose an unnecessary performance hit on your code every time you have to numerically manipulate the fields in your message.
Damn, these are the kinds of bugs I keep finding in my code!
Perhaps it’s time to find a new vocation?
Note: Thanks to @RiczWest for pointing this out to me.
Assume that the figure below faithfully represents two platform infrastructures developed by two different teams for the same application domain. Secondly, assume that both the JAD and UAS designs provide the exact same functionality to their developer users. Thirdly, assume that the JAD design was more expensive to develop (relative depth) and is more frustrating for developers to use (relative jaggy-ness) than the UAS design.
Fourthly, assume that you know that an agile team created one of the platforms and a traditional team produced the other – but you don’t know which team created which platform.
Now that our four assumptions have been espoused, can you confidently state, and make a compelling case for, which team hatched the JAD monstrosity and which team produced the elegant UAS foundation? I can’t.
On the left, we have N collaborating developers, N keyboards, and 1 product code base. On the right, we have the ultimate extension of pair-programming: N collaborating developers, 1 keyboard, and one product code base.
As a developer, which team development approach would you find more enjoyable? As a manager responsible for deciding how to allocate talented people to (hopefully) revenue generating projects, which approach do you think would produce higher quality software at a lower cost?
If you haven’t yet heard about the new rising star in the Agile family of methods, “Mob Programming“, but you find it compelling, here’s the ticket to your next 10X improvement in personal and team productivity:
Mob Programming Certifications (MPC) aren’t available yet, but have patience grasshoppa. They’re coming….
The figure below shows a series of “Grow And Fix” (GAF) cycles that models a software development effort. The gaps between each cycle represent external (to the team) deployment/usage/feedback periods. In practice, there usually are no gaps. After all, any upstanding org filled with managers who are paid to obsess over efficiency can’t allow for any idle machines between incremental releases.
Note that in the GAF way of doing things, the duration for producing a stand-alone increment varies from increment to increment. That’s because the GAF community thinks the act of arbitrarily setting T1 == T2 == T3 == T4 == T (like, say, T == 30 days) for every major increment is a pretty much stupid and dogmatic policy. As stated in the 16 page GAF user guide, the duration for each release is proportional to the breadth and depth of the functionality (f1, f2…. fx) allocated to the release.
In addition to the effort required for defining, creating and integrating new functionality into the growing system, the GAF method takes into account the effort required to “unbreak” existing functionality and to handle emergent, unexpected, behaviors that arise from function-to-function interactions (fix(f1,f2), fix(f1,f3)…).
For more detailed information on the groundbreaking new GAF methodology, including real success stories, endorsements, certification costs, books, T-shirts, hoodies, mugs, and upcoming community conferences, visit the GAF website. Enter the code BD00 at checkout to receive a 10% discount and free shipping on your first purchase.