5 Questions To Increase Systematic Reuse Effectiveness

May 13, 2013

Here are five questions to ask your teams to increase reuse effectiveness when evaluating a functional requirement:

  1. Is a requirement already met within the application or platform or is this the first time?
  2. If the capability already exists, does the current implementation provide the right extensibility? Often, existing code would need refactoring to meet a slightly varying set of requirements when compared to the original one. Take this as an opportunity to tease apart the abstractions necessary to capture the variations. What’s common and what’s truly different is the key aspect to figure out.
  3. Which other team or application has encountered this functional requirement before and how did they solve it? If you aren’t sure, ask around!
  4. Do we truly believe we are the first ones to stumble upon this need in the team/department/division/the firm? Try “laddering up” – as the Heath brothers call it in their latest book Decisive - incrementally and deliberately extract the key aspects of the problem you are trying to solve and look for places where solutions already exist. 
  5. If you find existing code to meet your need – evaluate it with a critical eye towards non-functional needs. Is it performant enough to meet the needs of your use case? does it provide adequate extension points / hooks to integrate with the rest of your application? is it a library or a hosted service? If hosted, what is the resiliency and availability strategy?

Too often, there is a bias towards implementing from the ground up due to either lack of time (don’t want to find out if other implementations or existing solutions exist and if they do, would they fit) or lack of trust (don’t want to use this team’s software or codebase or don’t trust that the quality of the implementation).

These aren’t exhaustive – what other questions come to mind?


Refactor Code Often, Continuously, Every Iteration

March 24, 2013

Refactoring is a way to improve code quality over time using incremental set of improvements – the idea is to increase the ability to make changes safer and faster and is not meant to deliver new functionality per se. For systematic reuse to succeed, refactoring has to happen often and on a continuous basis.  Why? It provides several benefits from a systematic reuse perspective. For instance:

  1. You will learn which aspects of the code base have the most technical debt – what’s complicated to understand and extend/enhance? which parts of the codebase are difficult to verify via automated tests?
  2. See repetition more often and will eliminate redundant methods, classes, even entire chunks of functionality – over time, you will see the same capability being provided by a different library, or there is a new requirement in a project that can reuse the capability if changes were made to it etc. Finally – and this happens to me a lot – you ask yourself – “what was I thinking implementing it a certain way when there is a better approach?”
  3. Systematic reuse needs deep understanding of the domain – the team needs to tease apart different technical concerns, identify which ones are relevant for the business, and identify variations within the scope of candidate reusable components. Which brings us to the most important question – are the assumptions made earlier about the domain and the subsequent design still valid? This continuous validation and re-validation of the core underlying assumptions and design choices will ultimately decide the reuse effectiveness of the component
  4. Over time, doing this will provide the team with a valuable data on providing estimates – which parts of the codebase are tricky? which ones lack tests? which ones are bug infested? All these aspects weigh into an estimate and continuous refactoring will give the team very good insights.

So, please don’t wait for a project or a deliverable to arrive – start refactoring every day and across every project :)


Paper On Incentive Compatibility and Systematic Reuse

March 10, 2013

This paper on Incentive Compatibility and Systematic Software Reuse provides several insights on incentives and organizational structure that will impact and influence systematic software reuse.  A few questions and points to ponder:

  1. Are you tracking cross project dependencies with an eye towards developing and sharing reusable components? Is this word of mouth, best effort or more systematic and instutionalized?
  2. Do you understand the cost of systematic reuse? what is the cost of discovering and evaluating a component for a particular use case? what is the cost of developer training and learning curve?
  3. How is funding allocated for ongoing maintenance/upkeep/bug fixes etc. for reusable assets? In short – how do you keep the program humming – will it become sustainable?
  4. Which role will provide the curator or expertise with reusable asset integration? Which role will provide guidance on when to use and when not to use a particular component?

This paper provides several models for enabling and operationalizing systematic reuse. There are several organizational considerations to picking and adapting these models. Regardless of which model is picked it should become quite evident that enabling reuse isn’t a purely technical endeavour. It is much more than that – from understanding the true costs behind reuse to continuous governance – it takes considerable effort and lot of discipline to get returns.


5 Tips to Co-Create Reusable Components

February 17, 2013

Want to envision, design, and implement reusable software components that your development community will enthusiastically adopt? Co-create! Here are 5 tips to leverage co-creation when driving systematic reuse initiatives:

  1. Have an idea that applies to multiple projects? Get the project leads to co-ordinate and align resources and partner with developers from both teams to develop the design
  2. Share the source code of all your reusable components so every developer in the team can see under the hood how the component works and how it can be improved
  3. Work hands-on with developers when defining classes, external interfaces, etc. – not just via block diagrams but actual code. Pair program and show them how to think using abstractions, what aspects of the design to make extensible and the rationale for it, etc. – you’ll be surprised how effective this is and how much all parties learn from the process
  4. Share the big picture – every time and across every project – developers and development managers need to be convinced that their contribution aligns with the overall technical strategy. This should also highlight why a shared component’s test coverage and robustness needs to be high and continuously improved
  5. Use design reviews, code reviews, and retrospectives to continually look for ways to collaborate and leverage each other. See boiler plate code that can be better encapsulated, or missing tests, or a smarter algorithm – get your hands into the code and work with the concerned developer. They will appreciate why you want them to use a particular design pattern or think about a problem in a certain way. Added bonus – just like item #3 – every participant will learn from the exercise.

Finally, co-creating reusable components greatly reduces friction associated with having to implement a design that was mandated. You want passion and enthusiasm from the dev community – not compliance!


Systematic Reuse Needs Extensibility

February 3, 2013

Accidental complexity is a real risk with trying to pursue systematic reuse . In trying to get reuse, you don’t want developers to jump through layers of indirection and complexity before they can write any useful code. Accounting for extensibility is a pragmatic approach when striving to design for systematic reuse.

Extensibility needs to be supported at various points in the design – it could be in user interface, integration, data contracts/definitions, system flows, services, and many other points. There are a plethora of choices and the question then becomes – how does one know what needs to be extensible? The answer lies in “finding what varies and encapsulating it”[1].

If a reusable component provides an extensibility hook – the consumer of the component can extend / replace default behaviour. Extensibility can be provided in a variety of ways – there ins’t a magic bullet here and each tactic needs to be considered in context. Here are various examples:

Spring Framework provides application context loader listeners that a developer can use to plugin custom logic. The listener doesn’t allow customization of how Spring constructs the beans or injects dependencies. However, it does provide a convenient mechanism for the developer to provide logic after container startup and before shutdown – place logic specific to a legacy/proprietary API that doesn’t support dependency injection. Alternatively, if there is a specific way to guarantee cleaning up resources prior to destroying context – that logic can be placed here as well.

Another extensibility strategy is from SLF4J - it is a logging facade and provides logging API methods that can be wired with concrete providers such as Log4J. Here, the idea is to free up individual classes from coupling with a specific provider. It provides much more points of extensibility than the above example.

Finally, the nature and number of extension points needs to be carefully weighed in the context of real applications. Not enough extension points hurts reusability. Similarly, too many increases learning curve, complexity, and possibly investment prior to making it usable in an application.

1. Alan Shalloway, James Trott, Design patterns explained: a new perspective on object-oriented design


Software Reuse Quick Tip #30

September 16, 2012

Tip #30 – Enforce Consistent Dependencies via Maven Parent POM

Maven parent POM can be used as a consistent mechanism to define dependencies and dependency versions. The module that defines common set of entries can then be used in any arbitrary module – it doesn’t have to be restricted to a child module in a multi-module build. This is very useful when you want to enforce consistent set of dependencies across multiple projects that share either a core set of reusable libraries including 3rd party dependencies.


5 Tips to Ease Reusable Asset Integration

September 9, 2012

Resuable software assets need to be created and evolved with two perspectives – functional value and ease of integration. A library that offers little functional value and is difficult to integrate into an application is unlikely to get wide adoption.  Are there tips to balance these two perspectives? I think so and here are some pointers:

  1. Minimize the number of 3rd party transitive dependencies – if reusing a module means bringing in 100 JARs, there are lots of opportunities for conflicting libraries build time and unanticipated runtime exceptions. I will elaborate specific strategies for this aspect in a separate post.
  2. Carefully assess integration points in your environment – does your company already have a widely adopted library for concurrency, logging, alerting, or messaging? Then your reusable asset needs to facilitate or ease out of box integration. Most importantly, it shouldn’t attempt to provide the same capabilities
  3. When providing overlapping capabilities you will have to convince the right set of folks that another API is necessary and there is a rationale for application teams to switch. Remember that the learning curve, integration effort, regression testing effort, and ongoing maintenance need to be factored into this decision
  4. When you are not sure how an existing library in your organization works, descope integration and instead focus on the core value that is unique in your reusable asset. It is much simpler to bolt that on rather than invest in an integration mechanism that you cannot support well.
  5. Boost developer productivity via IDE plugins, quick start project setup via Maven archetypes, or through code examples and automated tests. Regardless of what strategies you adopt the key is to demonstrate how easy it is to integrate your reusable asset with the rest of your enterprise.

Do these resonate with reuse practices you follow or have seen in your team? What other practices can help achieve adoption objectives?


Systematic Reuse Success Factor #12 – Empower Tech Architects

August 26, 2012

They key word in the phrase “systematic software reuse” is “systematic” – that is what distinguished ad-hoc reuse from continuous, iterative, investment-oriented reuse that provides benefits across projects. Anyone that has driven change within an organization will attest that one of the key enabling factors is political will and top-management sponsorship. Similarly, systematic reuse efforts need intervention and influence across every project – it needs your architects to have a say in the design and the implementation. Technical architects cannot be passive and standing back whining and complaining that the development teams aren’t listening and they aren’t reusing existing assets or investing in creating new ones. In addition to hiring competent architects, management needs to empower them. They need to be given authority and made accountable for systematic reuse efforts – want architecture convergence? faster time to market? lesser cost of maintenance? All of these are possible with systematic reuse but only with proper investment and ongoing guidance and care.

Empowered architects should be able to alter/change the technical strategy, design, and implementation approaches to ensure that it is inline with the overarching technical strategy for reusing capabilities within the teams. Of course, this doesn’t mean they stop everything without delivering value to clients on a continuous basis. On the contrary, architects need to be focused on both alignment with reuse and business delivery. They need commitment from teams that pursue tactical measures that they will get out of technical debt and align completely with the technical strategy.  They should and be able to intervene throughout the development process – during requirements analysis, design, implementation and review by working with the development teams in a hands-on fashion. If the architect carries no decision making authority to stop releases, change approaches, or extract commitments – the technical debt will stay where it is and reuse will be an elusive goal.


Tools and Software Infrastructure for Systematic Reuse

August 24, 2012

A lot of readers have asked me to provide details on what tools and software infrastructure is needed to enable systematic reuse. That is a very good question and it is a critical enabler for building on early wins with reuse.  At a minimum you need to setup the following as your asset base grows:

Module Structure: how are the reusable components organized in your codebase? For starters, setup a separate multi-module build for segregating resuable components from application (or consumer) code. The reusable components should be versioned, managed, and governed separately using a proper release cycle outside of the application code. Each component will also need a comprehensive set of automated tests.

Dependency Management: Use ant/ivy or maven if you are using java for building reusable assets. Each module should have the absolute minimum list of internal and 3rd party library dependencies. Each module should make sure that dependency scope is marked appropriately – take care to mark dependencies in test, runtime, and provided scope as required. Finally, ensure the build is using a clean set of dependencies – remove conflicting/redundant dependencies, and remove dependencies that will conflict with consumer code if possible as well.

Code Quality: Reusable components have robust code quality tooling in place. Use checkstyle, FindBugs, and clover/cobertura etc. with the build script. If you are using maven, you can declare these as plugins and generate code quality reports alongside your build. If you want an integrated code quality dashboard and web based reporting, setup Sonar!

Continuous Integration: Automated tests and continuous integration are extremely critical to continuously refactor, enhance, and deploy resuable components. Setup a continuous integration server that kicks of automated builds on commits as well as when dependencies get updated. Setup a CI server such as Hudson to run unit, integration, and regression tests

Asset Repository: Once you build components, there needs to be a binary repository to host them and integrate them into other builds. Artifactory repo (provides open source and commerical versions) and can be used to house your reusable components (in fact any component really). Once the web GUI is setup, you can browse and search for artifacts as well as refer to them from internal build configurations.

Issue Tracking: Setup bugzilla or your favorite bug and issue tracking software so teams within your organization can submit bug fixes and enhancement requests. You will also need to publish and manage a release calendar to provide transparency into which reusable components are getting released when and how are they getting delivered in the context of real business deliverables.

What additional tools and practices do your teams follow?


Getting Started With Reuse By Harvesting Existing Code

August 23, 2012

Many teams want to incrementally build a portfolio of reusable components so multiple projects can leverage them. This post will provide a list of potential areas to look for achieving systematic reuse – chances are that you have a few components in these areas already. Assembling them into a standard set and making it available for easy consumption will dramatically increase adoption rates across projects. Here are the areas to invest and/or harvest existing code:

  • Configuration – specifically properties that vary across environments (e.g. DEV, QA, PROD). How are teams defining and managing this information today? If you are using Maven,  teams may be employing multiple strategies – profiles, assemblies, custom scripts, naming conventions, etc.  Why not consolidate practices?
  • Transformation APIs – many projects require data transformation between objects to JSON or objects to XML and vice versa. Teams might be using different transformation libraries, may be wiring them with Spring or other dependency injection frameworks in a bespoke manner. Why not adopt a consistent API that provides transformations via a common set of classes with pluggable format-specific providers?
  • Flexible Query Construction – lookup methods that require one or more parameters will end up having common boiler plate code that binds parameters using boolean conditions – why not provide a reusable API that allows the developer to wire parameters using a common API?
  • Integration with internal and/or external systems – retrying, alerting, message construction, metrics, and proactive monitoring are all cross cutting concerns that are common across projects. Teams must be realizing these capabilities using multiple APIs, injection hooks, and response loops – again a consistent and reusable API will not only cut development costs but also make application support simpler

Existing code and components do however carry several risks that have to be addressed to realize reuse potential. For example:

  1. How domain agnostic are the components? Does it have a well defined interface and ability to adapt to a family of use cases?
  2. What is the learning curve for developer adoption? Does it have well defined adoption patterns that are easy to learn and intuitive?
  3. How testable is the component? Does it have interfaces that capture and model varying behavior ?
  4. What is the support model for the component? How to submit bug fix or enhancement requests? is there enough expertise in the developer community?
  5. What will be the release cycle for reusable components ? This becomes critical as more projects start to leverage a common suite of components for a varying set of capabilities

Follow

Get every new post delivered to your Inbox.