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 :)


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

Accelerating Reusable Component Adoption

August 11, 2012

When building reusable components, you want  to allow rapid component discovery, assembly, and testability. Without these characteristics, it will become difficult for developers to use the reusable components in a productive manner. Below are five things to do to accelerate component adoption:

  1. Provide examples on how to wire the reusable component with widely used proprietary or external frameworks
  2. Make it easy to use sensible defaults with frequently used features – if almost every application needs a particular feature, why not make it the default option?
  3. Open up the source code and invite feedback and improvements – chances are high that your development community has tons of ideas to make use of reusable component in new and innovative ways
  4. Engage early in the development lifecycle – don’t want till the very end to evangelize / educate teams about the component – actively and continuously engage with the developers to look for integration opportunities
  5. Tie code review feedback to component adoption – spotting code that has traits such as duplication, inefficiency, unmaintainable? Treat every defect as an opportunity to remove technical debt and increase consistency

These are by no means exhaustive and key is in performing them in a disciplined manner project after project.

 


Systematic Reuse Mythbuster #1 – Reusable Doesn’t Mean Perfection

December 26, 2011

One common criticism against systematic software reuse is the myth that it implies perfection – creating a reusable asset automatically conjures up visions of a perfect design, something that is done once and done right.  Many developers and managers confuse reusability with design purity. However, reusability is a quality attribute like maintainability, scalability, or availability in a software solution. It isn’t necessary or advisable to pursue a generic design approach or what one believes is highly reusable without the right context.

The key is to go back to the basics of good design: identify what varies and encapsulate it.

The myth that you can somehow create this masterpiece that is infinitely reusable and should never be touched is just that – it is a myth and is divorced from reality. Reusable doesn’t imply:

  • that you invest a lot in big up front design effort
  • you account for everything that will vary in the design – the critical factor is to understand the domain – well enough, deep enough, so you can identify the sub-set of variability that truly matters

In the same vein, reusablility strives for separating concerns that should be kept distinct. Ask repeatedly:

  • Are there multiple integration points accessing the core domain logic?
  • Is there a requirement to support more than one client and if so, how will multiple clients use the same interface?
  • What interfaces do your consumers need? is there a need to support more than one?
  • What are the common input parameters and what are those that vary across the consumer base?

These are the key questions that will lead the designer to anticipate the appropriate places where reuse is likely to happen.  Finally, it is important that we don’t build for unknown needs in the future – so the asset is likely to solve a particular problem, solve it well, solve it for more than one or two consumers, and finally has potential to be used beyond the original intent. At each step there are design decisions made, discarded, continuous refactoring, refinements to the domain model – if not re-definition altogether.

Don’t set out trying to get to the end state or you will run the risk of adding needless complexity and significant schedule risk.


9 Quick Tips to Reducing Technical Debt

April 13, 2011

Wrote earlier about the importance of refactoring and continuous alignment within the context of systematic reuse effectiveness. Reducing technical debt is an integral aspect of refactoring. This post provides tips for reducing technical debt in your software assets:

  1. Minimize redundant definitions of key domain objects (i.e. competing, conflicting definitions of the same domain object across related applications)
  2. Minimize similar solutions for slightly varying business processes and instead create common process flows
  3. Loosen tightly coupled integration/transport logic with business logic
  4. Provide consistent strategies for implementing cross cutting concerns
  5. Replace tactical implementation for a problem that has a better open-source alternative
  6. Eliminate redundant approaches for managing configuration information
  7. Harmonize multiple, incompatible interfaces and make them more domain relevant
  8. Minimize excessive coupling with a particular technology/implementation stack
  9. last but not the least – create a comprehensive suite of automated tests

Are there similar themes in your development efforts? What steps are you taking to ensure technical debt is addressed?


Agile Software Reuse Design Practices Primer

March 5, 2011

Pursuing systematic reuse the agile way? This primer will cover a variety of design practices to help your development teams. It covers:

  • Building reusable assets from existing applications
  • Designing new reusable components and services
  • Design patterns, product line practices, and more!

Domain Analysis Key To Systematic Reuse

November 26, 2010

Domain analysis is a foundational capability required for effective systematic reuse. Why? There are a lot of applications your teams are working on and the common theme among them most likely is the fact that they are in the same problem domain. In order to truly bring down cost of new applications and services, it is critical that the domain is understood and modeled appropriately. Here are some specific strategies to make this idea operational:

  1. Account for domain analysis and modeling in your iteration planning. Domain analysis is necessary to understand the nuances and variation points that an application/service/process needs to realize. Discovering the right variations requires time and interactions with business stakeholders and subject matter experts.
  2. Aspire for a core set of business object definitions that can be shared across business processes and service interfaces. Without appropriate data governance, domain knowledge will either be inaccurate/incomplete or worse duplicated in an inconsistent fashion. As the number of customer interfaces increase for your services, the domain inconsistencies will lead to greater point-to-point integrations and complexity.
  3. Align overall architecture with domain variations. Your domain is rich and complex but probably varies in a known set of ways. Additionally, what varies isn’t uniform and the rate of change across these variations aren’t identical. This is significant because the variations in the domain need to be captured in your overall architecture. Products/applications in the domain need to share a common architecture – only then can components integrate and inter-operate and systematic reuse will take hold. Constantly evaluate the need for a new version of a core business entity and associated classes to manage the entity.
  4. Refactor constantly to get to intention revealing design and code. As Eric Evans illustrates in Domain Driven Design, intention revealing code is easier to understand and evolve.  It also makes it easier to address new business requirements – as the design/implementation are closely aligned with the business domain, the quality of communication (referred to as ubiquitous language) and the ability to change it both increase significantly.

This isn’t an exhaustive list – instead, it is meant to highlight the need for placing the domain in the middle of every design, architecture, and implementation decision your teams make.


Practicing Continuous Alignment – Examples

September 5, 2010

Received an email from a reader on the continuous alignment post and wanted additional examples. Practicing continuous alignment entails refactoring existing code to align assets better towards a reuse strategy.

Here are a few scenarios where refactoring opportunities can be utilized:

Horizontal logic mixed with app-specific logic: This is typically manifested in two flavors – cross-cutting functionality that is horizontal across several applications or domain-specific functionality that is applicable to a product line. Cross cutting functionality such as authentication, logging, error handling etc. can be refactored from app-specific to distinct components.

Redundant definition of business objects: maybe two or more of your projects are redefining a core concept from your problem domain and refactoring can help align them to a common definition. Once a common definition is used, add tasks into your iteration plans.

Manage application configuration: If several applications use ad-hoc set of practices to manage runtime configurations (e.g. xml configurations, property files etc.), refactoring them to use a consistent strategy would certainly make sense. This refactoring can be done one component at a time if time constraints make it harder to transform an entire suite of components in the app.


Transforming Object to XML using Freemarker

August 22, 2010

I wrote earlier about using open source software for fulfilling functionality prior to building a custom implementation. Many projects have the need to transform object to text or XML – e.g. return XML response for REST-based services or return JSON string to support a web application etc.

Freemarker is a templating engine that can be leveraged to perform object to text transformations – with freemarker it is easy to generate RSS feeds or delimited text or plain old XML very easily. Below are some code fragments that illustrate freemarker usage:

Below is a code fragment for setting up the template configuration:

try {
	// Initialize configuration;
	cfg = new Configuration();
	cfg.setDirectoryForTemplateLoading(new File(templatesLocation));
	cfg.setTemplateUpdateDelay(0);
	cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
	//Use beans wrapper (recommmended for most applications)
	cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
	cfg.setDefaultEncoding("ISO-8859-1");
	//charset of the output
	cfg.setOutputEncoding("UTF-8");
	//default locale
	cfg.setLocale(Locale.US);

} catch (Exception e) {
	//handle the exception
}

The templatesLocation variable is the path to a folder with freemarker templates (referred to as FTL templates). These are similar to templates used with frameworks such as Velocity. For example, below is a template fragment:

<Name>${myBean.firstName?xml} ${myBean.lastName?xml}</Name>

“myBean” is the java object that has first name and last name properties supported by JavaBeans style getXYZ() methods. The ?xml built-in function is used to encode any special XML characters.

Below is the code fragment when trying to invoke a template with a java object – the template file name is hard-coded for below example – it can be fetched from an input parameter or injected directly into this object as necessary:

// loading the template file
String templateFileName = "test-template.ftl";
Template template = cfg.getTemplate(templateFileName);
Writer out = new StringWriter();
template.process(dataObject, out);
String strResponse = out.toString();

The above code fragment essentially takes a java object (dataObject) as input and creates a string as output. Using the template above, the output for example could be:

<Name>John Smith</Name>

Freemarker also supports loops and conditions and offers a rich library of built-in functions as well.


In a hurry to decide if something is reusable?

August 15, 2010

I have heard some variation of the following line from developers, technical leads, and architects – “we want to make things more reusable, but we don’t have the time.”

There is always a deadline (or many deadlines) to meet and technical debt to accumulate. Since we are always in a hurry, it helps to be aware of what should be reusable – even if we won’t get to it in this iteration . So here are some ideas that can help you decide whether or not a capability should be developed for reuse:

  • is the capability unique to your enterprise? i.e. it captures logic and/or process variations that provide competitive differentiation.
  • is the capability making something incredibly hard/defect prone simpler and/or easier?
  • is there a desire for customers to have a capability across business channels? i.e. from the web, from a mobile device etc.
  • is it specific to your domain and potentially relevant to multiple applications in the domain? this may or may not be obvious – if it isn’t, delay commitment.
  • is the capability only available in a particular technical platform but is solving  an often needed problem?
  • is it automating boiler plate code generation or preventing defects?
  • is there an in-house/external alternative that achieves your functional requirements? if so, seriously consider stopping investment in the asset.

This is a starter list – the idea that we keep coming back to is this – treat a reusable asset like a real investment. Every iteration and release is an opportunity to review and update the investment. When you make a decision, continuously refactor to make the capabilities less app specific and reusable.


Follow

Get every new post delivered to your Inbox.