Why do we fear Continuous Refactoring?

April 22, 2010

There are so many reasons why continuously refactoring code is a good idea – in fact, it is a sound investment for the overall health of your codebase. So, what could be some reasons why we fear doing refactorings? what could be the impediments to making changes?

In my experience, the #1 reason why developers fear refactoring is the lack of automated regression tests. This is why Martin Fowler emphasizes the need for tests prior to pursuing refactorings in his seminal book Refactoring. Without a comprehensive suite of tests, developers cannot be confident that changes to the code didn’t break existing functionality and it didn’t introduce new defects.

There are other reasons as well for fearing refactoring:

  • Not enough time during development – this is such an often repeated reason for a variety of issues 🙂 Here is the rub though: we learn most about the domain and the limitations of existing code with experience. This tends to happen at the “end” of an iteration or release cycle. Naturally, we don’t want to jeopardize our release to do refactorings. This is precisely why agile advocates the notion of continuous refactoring iteration after iteration. Your code reflects the state of the software (and the associated knowledge of the domain) at a snapshot in time. It is a work-in-progress – remaining that way till the product ceases to exist or be maintained.
  • Lack of disciplined effort to translate new domain knowledge into existing code. As a project proceeds, developers learn more about the domain and the gaps in their knowledge with respect to the domain. These gaps typically manifest themselves in various forms: needless abstractions, insufficient flexibility with known variations in the domain, and lack of domain-relevant concepts being modeled as first-class citizens.
  • Insufficient knowledge on using refactoring tools (e.g. using an IDE such as Eclipse, there are a plethora of refactorings can be implemented rapidly).
  • Lack of knowledge about refactoring tactics – moving methods, creating interfaces, replacing if..then logic etc. – that are necessary to keep a tidy, effective codebase
  • Unwillingness to improve the codebase on a continuous basis 🙂

Building Assets Iteratively – An Example

April 13, 2010

Building reusable assets iteratively helps your team in several ways: reduces technical and business risk, reduces time to market, and increases the odds of real-life usage across applications. In this post, I wanted to walk through an example of iteratively building a reusable asset. Our task was to create a suite of services for providing core data such as customer data and product data to various internal applications. To support these services in production several non-functional capabilities were required. These capabilities needed to be reusable across services – i.e. we didn’t want to develop something that would only work with customer data and not product data. Note: this effort was before mature SOA governance tools started to appear – so if you are thinking “why did they build this?” – because it didn’t exist at that point in time 🙂

Iteration 1: Simple logging to log requests, responses, errors

Iteration 2: Configurable logging – ability to change logging levels without restarting the service container

Iteration 3: Ability to enable/disable service capabilities via a service interface – a web service end point that would turn on/off services (we had business reasons to support this capability)

Iteration 4: Toggle service capabilities via a web interface – integrated functionality from Iteration3 to be able to perform the toggle via a browser-based front end application.

Iteration 5: Get statistics about a service capability – usage metrics, distribution of error codes, etc. was available for every service capability.

Iteration 6: Enable/disable HTTP endpoint – to enable/shut off access to a HTTP port that was listening to service requests.

Iteration 7: Enable/disable JMS endpoint – to enable/shut off access to a JMS queue that was listening to service requests.

Iteration 8: Toggle transport endpoints via a web interface – integrate functionality from iteration 6 and 7 with our web based console application.

Iteration 9: Get usage statistics filtered by consumer, date and time, and various other fields.

Iteration 10: Integrate usage statistics querying with web based console application.

These iterations were executed alongside business functionality – the interesting aspect of this – and something that all agile methods emphasize – is that we learned from real-world service usage and troubleshooting in production. We didn’t have to dream up requirements – as we gained deeper knowledge of how services function in production, the needs emerged naturally. Coupled with reviewing logs/production statistics and interviews with service consumers we were able to prioritize the supportability tools that were needed.

Just Enough Design For An Iteration

October 11, 2009

You can practice minimal design to be effective with systematic reuse. The design needs to continuously look for opportunities to align iteration goals with your systematic reuse roadmap. Too many developers mistakenly think that adopting agile means abandoning design. This couldn’t be farther from the truth. You design whether you explicitly allocate time for it or not. Your code will reflect the design and you will impact the technical debt for your codebase in one way, shape, or form. Implementing user stories and paying down technical debt should be your end goal and not avoiding design altogether.

The first priority is to design for meeting your iteration goals. Avoid designing for several weeks or months and surely avoid putting technical perfection ahead of delivering real user needs. You should design minimally. Just enough to take advantage of existing reusable components, identify new ones, and plan refactoring to existing code. Specifically this means:

  1. Keeping a list of short term and medium term business goals in mind when designing
  2. Always looking for ways to make domain relevant software assets more reusable
  3. You are aware of what distribution channels your business is looking to grow
  4. Design reflects the domain as close as possible and that your reusable assets map to commonly occurring entities in your business domain
  5. Value is placed on identifying the product lines that your business wants to invest in and evolving your reusable assets to mirror product line needs.
  6. Design isn’t a pursuit of perfection but an iterative exercise in alignment with your domain.

What you decide to encapsulate, abstract, and scale are all natural byproducts of this design approach. Rather than spend a lot of effort with big upfront design you can do just enough design.

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook

Have a plan for every reusable software asset

May 10, 2009

Have a plan for every reusable asset. At a minimum the plan needs to address:plan

  1. The scope of the asset’s functionality for your immediate deliverable
  2. The asset’s place in within your product line
  3. The impact to your existing design and overall architecture
  4. Tentative road-map for evolving the reusable asset over several iterations or releases

You don’t have to get answers for all these areas rightaway! The point is to think about them so you can make decisions on scope and effort. In the midst of an iteration there will be several questions about whether or not to invest time in refactoring or developing a feature. You can use this tiny list as a guide to help you make decisions on what to refactor or build and whether or not it is in line with your overall strategy.

Like this post? Subscribe to RSS feed or get blog updates via email.

add to del.icio.us: Digg it : post to facebook: Stumble It! : :

%d bloggers like this: