Success Factors for Systematic Reuse
Systematic reuse requires the interplay of people, process, and technology decisions that have to be executed within the context of real world constraints. Are there success factors that will make a difference to reuse? I believe so! This article provides five success factors that will help capture domain variations, ease integration, delve deeper into design context, work effectively as a team, and manage domain complexity.
Capturing Domain Variations
Capturing necessary variations in the domain is extremely important to systematic reuse. Business domains are filled with variations that need to be identified and managed across your codebase. Product line variations are at the heart of effective software reuse. To identify variations in your domain you need go seek subject matter experts as well as end users in your shop. Work with them closely to understand the domain, the aspects that tend to vary often, and how these variations are manifested in user stories. From the customer’s point of view, these variations are a natural way of how their business functions. Invest time to make sure that you not only recognize variations as a whole but also identify the subset of variations that really matter.
Given the pragmatic nature of software reuse that is necessary, it is unrealistic to identify all variations in a problem domain. Your iterations will not happen and working software won’t get delivered unless you can include and adapt domain variations as part of your development practices. From a design perspective there are some questions that will help you. Every time you look at a user story you should ask yourself:
- What domain entities are involved?
- Are there entities being encountered for the first time?
- Is this story requested in more than one product or application?
- What aspect of the domain varies in the story? Some common variations tend to recur - the kind of user who uses a feature, number of features being offered, differences in behavior for a feature or a group of features, how features are bundled together based on business criteria, interface metaphors and themes, and reporting/charting capabilities
- Are there a set of user stories or aspects of user stories that appear together often?
An often overlooked aspect of systematic reuse is integration of reusable assets with applications, processes, and services. Most teams focus on building a large inventory of reusable assets - services, objects, frameworks, domain specific language libraries. While that is necessary it is not sufficient for succeeding with systematic reuse. One essential ingredient is ease of integration. What do I mean by that? Specifically:
- Evaluating the requirement and making a determination whether an existing asset can fulfill the need (as-is or with modifications) or a new one needs to be developed
- Address risks with integrating with a reusable asset (meeting service level agreements (SLAs), solution complexity, etc.)
- Sharing information on available interfaces (is there a java interface? a web service?)
- Providing code samples and integration design patterns
- Provide comprehensive list of error codes and error handling recommendations - if a service throws a particular error what should the consumer do? are there specific business errors or data validation errors that the consumer needs to be aware of?
- Ensuring the consumer doesn’t starve the reusable asset’s resources - This is essential for services based reuse where multiple consumers are invoking the same service capability
- Assistance with testing the integration (provide test data, unit test code, as well as utilities to test response time/throughput)
You can build up a service catalog and magically hope to achieve a high degree of reuse, but you will most likely be disappointed. Reach out to your consumer and help them succeed. Make it easier for them to evaluate, integrate, and test. Slowly but surely your teams will start coming to you as opposed to you trying to ’sell’ them on the value of reuse!
Understanding Design Context
There isn’t just one right way to build reusable software assets. Your business goals, technical environment, iteration and release plans all contribute to both the timing and nature of design decisions. Refactoring existing code to meet business goals is also context driven. Consider:
- What product features typically go together?
- Do certain features vary more than others across products?
- Is it possible to vary a product feature at runtime or design-time?
All these questions guide design. For instance, if the goal is to support variability at runtime, you could support adding new parameters and changing existing ones without code changes or application restarts. As you work on design, keep your domain-relevant variations at the back of your mind!
Take an example of a widget shop that needs to market its widgets. The user story is to produce different marketing labels based on widget type. There could be several variations to support - frequency of changes to label information, number of words, language, data formatting, mixture of static and dynamic messages that make up a label, etc.
Depending on the complexity of your domain, the features could vary simultaneously or in isolation. Consider some of these variations and their impact on design:
- Label contents are only static content - you could use a single LabelGenerator using a file configuration.
- Label contents are a mixture of static and dynamic content - LabelGenerator now needs two sub-components - a StaticContentGenerator and a DynamicContentGenerator.
- Label contents are a mixture of static and dynamic content. Static content is multi-lingual. - In addition to the content generators you need an internationalization component that can support multiple languages
- Label contents are a mixture of static and dynamic content. Static content is multi-lingual. Date and currency formatting varies based on country - All components of #3 plus a DateFormatter and CurrencyFormatter based on locale.
Next time you start a project, understand more about the drivers for change in your problem domain. Your domain and the associated context should drive reuse. The more you understand the drivers, the easier it is to decide what and how your software assets need to be reusable.
Working alongside some very interesting and high-performance teams, I have come to believe that success with reuse is more than technical brilliance or elegant design. Great teams produce high quality work, understand each other, their strengths, their limitations, and most importantly harness conflict as a medium for healthy constructive dialogue, creativity, and innovation.
Why is teamwork relevant to systematic reuse? Because, producing something reusable under severe deadlines and delivery pressures, integrating with legacy systems and processes, working with a myriad teams spread across several organizational departments, geographies, and still delivering high quality products is incredibly hard. It is the kind of challenge that motivates technology leaders and professionals to go to work and make a difference.
The fundamental technical concepts for systematic reuse are well understood and what differentiates the winners from the rest of the pack is their ability to execute the reuse vision within their business domains with the help of productive teams on the ground. Every single component, service and asset matters.
Extraordinary teams talk to each other often, exchange ideas and collaborate more effectively, and most of all identify and mitigate risks to ensure the team as a whole is best positioned for success. If this sounds a lot like the agile manifesto it is not coincidental! Building reusable services require creative brainstorming, conflict resolution, design synthesis, and arriving at a logical point that will be used to deliver your iteration. This isn’t an event - its iterative, continuous, and execution-focused. If your team blends creativity and continuous delivery, systematic reuse will be a natural byproduct.
Managing Domain Complexity
Your domain might be complex and rich in variations that need to be supported. Trying to capture all the complexity is neither pragmatic nor feasible given the constraints you might be under. Instead, focus on the essential complexity. In addition, it is unlikely that your business supports all the variations in your problem domain. Fortunately most domain variations are expressed as user stories and you can look for patterns across iterations and releases to get a better understanding. Deciding the sub-set of complexity to manage is an art and you will need to continually collaborate with folks on your team on this.
I use a set of simple categories to look for areas that have essential domain complexity. This list is by no means comprehensive but it gives you a sense of what could drive complexity:
- Data capture: The system might have multiple user roles, and the kind of data, validations and rules that execute on them all vary
- Geography: Variations based on geographic regions/countries/states including differences in language and date/time formatting
- Combination of product features (also called bundling): Variations to support different product flavors (e.g. basic support features X, Y, and Z; professional supports features X, Y, and K; and premium supports A, X, Y, and K)
- Entitlements: Variations in access to different parts of a system and perform varying tasks. Related to user population and transaction behavior as well
- Transaction behavior: Variations in transaction behavior in terms of monetary limits, approvals/validation rules, how business exceptions are handled
- Channel (also called a distribution channel or sales channel): Product availability, feature availability, security, customer support, frequency and kinds of marketing communications, etc.
Next time you examine a user story, place it in light of your domain categories. Is it a recurring pattern across iterations? If so, you should add it to your systematic reuse roadmap. Don’t panic if managing domain complexity doesn’t influence your design from day one. Nothing here is about embarking on a big upfront design effort to manage all this complexity. You should differentiate between awareness and action. Your increased awareness of your domain will help you align your systematic reuse efforts with business aspirations and iteration goals. Think of this as your refactoring guide that helps you make surgical changes to your codebase.
This article elaborated on some of the success factors that will aid in your systematic reuse efforts. Without managing and understanding the problem domain it is futile to design reusable assets that will serve as a useful investment for addressing business needs. By working effectively as a team and easing integration for your consumers you will increase your odds of success with reuse efforts.
About the author
The author is a software professional building reusable data services and business process automation components. He has worked on several software projects ranging from single user systems to large, distributed, multi-user platforms with several services. He is a contributing author for an upcoming book on SOA and a speaker on agile techniques. He blogs about systematic software reuse at http://www.artofsoftwarereuse.com/
InfoQ Sep 01, 2015