Stop Planning & Start Harmonizing Implementations

November 2, 2013

You can wait for that dream initiative or project to build a whole new set of reusable components that will magically make your teams more productive. The only issue is – it is highly likely that it will be just that – a dream. Instead of planning for systematic reuse, start executing on it by taking a few simple steps. Ask yourself the following questions:

1. Are you capitalizing on identifying and sharing common components with your department / team?

2. Is every project encouraged to continuously refactor and harmonize classes for reducing redundancies? If not, why not?

3. Do you have code that caters to common infrastructural concerns – logging, exception management, alerting, monitoring, metrics.? If yes, is their reuse mandated via common framework hooks that your developers are already using? If not, what is preventing adoption of these concerns into your development stack? Ask your developers and listen to their concerns – you will need to unearth and attack the root causes behind reuse barriers.

4. Do you utilize ad-hoc, informal pairing and code review sessions to identify and harmonize similar / duplicate / redundant classes? If you review code the first time before a project go-live, odds are you either will regret missed opportunities or bemoan the lack of time within your development cycle for making improvements. Key is to intervene early and often and front load your investments for systematic reuse

5. How do you ensure reafactoring to reuse opportunities are tracked? do you create improvement tickets and action them on a best-effort basis or are they managed as part of the product backlog of things that have to get done? If its the former, it will be difficult to make much progress. Creating and tracking tickets will will provide visibility – however, for you to make tangible progress in acting on them you need to partner with developers and development managers to action work on an ongoing basis.

These are just example questions to help you get your journey started and it should be abundantly clear that discipline and continuous alignment is key. If you don’t do anything else, just force your team to converge on a common implementation on key functionality. You will be surprised what discipline can deliver.


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 🙂


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.


Understand Why Asset Isn’t Being Reused

July 13, 2010

Some software assets don’t get reused – question is – is the reason well known? if so, what is being done to ensure that it doesn’t happen too often? In agile methodology, the retrospective serves as a vehicle to reflect on the iteration. Reflecting on the experience overall – what worked, what didn’t work, how can the team improve and so on.

In the same token, consider retrospective for reusable assets – did the asset get used the way it was intended to be used? if not, are new use cases providing opportunities that weren’t considered earlier? In the rush to perfection, there is always a danger is adding too much complexity to an asset. Are consumers even using all that complexity? remember there is a cost to complexity – having the right level of complexity with multiple instances of reuse is a happier place to be.

When you work with the internal development team and asset consumers – ask them specifically why something isn’t working. Is it the lack of adequate documentation and/or code samples? does the asset fail because it didn’t have domain relevance? are there better (cheaper, faster, more maintainable) ways to achieve the asset’s functional objectives? is it too slow and doesn’t meet performance SLA needs? are there too many configuration options? doesn’t work well in a particular runtime environment?

You get the idea: there are specific reasons why your software asset isn’t being reused. Find out why – continuously refactor and resolve root causes to get a higher return on your software investments.


Build for Use, then Refactor to Reuse

July 11, 2010

You want to build reusable assets in an agile manner – avoiding a significant design effort upfront and evolving behavior over time.  Why? Because building for reuse involves several steps: the right abstractions have to be identified, appropriate variations have to be modeled and accounted for, and the asset has to be generic enough for use beyond a single project.

This is hard to get right the first time – often, business requirements aren’t clear from the early on making it tricky to identify reusable assets. More importantly, reuse adds project risk – specifically risk to the timeline. Always ask yourself if it is worth making the extra investment – if you aren’t sure delay commitment.

Capture possible enhancements to your codebase via an issue tracking tool and you can always assign those enhancements to future iterations. When you implement a story and you see the opportunity for making something reusable, consciously align classes and interfaces for reuse. Refactor, refactor, and keep refactoring – because only with multiple iterations is your asset going to be increase it’s reuse potential. Remember – very often, the asset would not be used as-is. It will need changes – patches, enhancements, major redesign even – before it can be leveraged across projects.


Refactoring to Reuse #5

April 17, 2010

#5 – Replace Custom Implementations With Open Source Equivalents

I realize this is a very large category with possibly several dozen examples. In this post, I will highlight this strategy using the Apache Commons IO API. Many applications require the need for accessing file data – reading input business data or even temporary file data is a common need. Typically, you have some class that opens a file, reads data line by line, and either returns a custom java object or a string buffer.

FileReader fr = null;
 BufferedReader reader = null;
 try {
 fr = new FileReader(strFileName);
 reader = new BufferedReader(fr);
 String line = reader.readLine();
 while (line != null) {
 //do something with the line of data...
 line = reader.readLine();
 }
 } catch (IOException e) {
e.printStackTrace();
 } finally {
 try {
 if (reader != null) {
reader.close();
 }
 } catch (IOException e) {
e.printStackTrace();
 }
 }

How many times have you written this kind of logic? 🙂 When you look to simplify this or want to reduce repetition, consider the Apache Commons IO library. The FileUtils class offers just the method you need for accomplishing the often needed line by line data access to a file. It is trivial to use. For example, see below:

import org.apache.commons.io.FileUtils;
//other lines of code and class declaration omitted...
String strFileName = //path to file...
try {
   File f = new File(strFileName);
   List fileDataLines = FileUtils.readLines(f, "UTF-8");
} catch (IOException ioe) {
 ioe.printStackTrace();
}

That’s it – giving you the same functionality using a far simpler interface. There are several advantages to using these libraries – they are open-source, well documented and tested, and eliminate a lot of redundant code in your application. Travel light and only code stuff that you absolutely must. As I have highlighted before – reuse and agile go hand-in-hand. Less custom code you write, less maintenance for your team.


Refactoring to Reuse #4

November 13, 2009

#4 Separate Message Construction from Message Delivery

There are a variety of scenarios where you will build a message and deliver it to a destination. The message itself could be free-form text, delimited/fixed-length text, XML, or some other format. The destination itself could be a system, service, application, a server, or a human user or group of users (in the case of email). If you decouple message construction from its destination, that will drive in reuse of both of these assets. For example, you can take a message and send it via email or send to a message queue. In the same vein, you can potentially use the same code that sends email to send a newsletter message and a reminder message.

To illustrate this idea, take a look at this code fragment:

MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress("someone@xyz.com"));
message.setSubject("Hello there...");

FileReader fr = new FileReader("some-template.html");
StringBuffer sb = new StringBuffer();
BufferedReader reader = new BufferedReader(fr);
String line = reader.readLine();
while (line != null) {
     sb.append(line);
     line = reader.readLine();
}
reader.close();

message.setText(sb.toString());
// Send message
Transport tr = session.getTransport("smtp");
tr.connect("host-name", "user", "some-password");
message.saveChanges();
tr.sendMessage(message, message.getAllRecipients());
tr.close();

There is a file that is read from the file system and a data buffer is being constructed. The data is then used to send an email. However, this class isn’t very reusable because of the tight coupling between message construction and delivery logic.

Now examine, a newer version that has modularized this code – Publisher sends the message using an EmailConfiguration and TemplateBuilder constructs the message using an instance of Template.

Publisher publisher = new Publisher();
EmailConfiguration eConfig = new EmailConfiguration();
publisher.setConfiguration(eConfig);
TemplateBuilder builder = new TemplateBuilder();
Template template = builder.build();
publisher.publishMessage(template);

Now, Publisher, EmailConfiguration, Template, and TemplateBuilder are all candidate assets that are available for other classes to reuse. If you have other types of configurations, they can be included as well and bound polymorphically. This concept can be further extended based on the quantity and quality of variations. For instance, the message construction can be realized using a common interface with multiple implementations. The message itself might have standard and personalized content.

You may move to a more modular version iteratively. Which version do you think facilitates reuse, faster integration, and higher productivity? This new design will make it easier to test message construction independently from publisher.
Like this post? Subscribe to RSS feed or get blog updates via email.

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

MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress("someone@xyz.com"));
message.setSubject("Hello there...");

FileReader fr = new FileReader("some-template.html");
StringBuffer sb = new StringBuffer();
BufferedReader reader = new BufferedReader(fr);
String line = reader.readLine();
while (line != null) {
     sb.append(line);
     line = reader.readLine();
}
reader.close();

message.setText(sb.toString());
// Send message
Transport tr = session.getTransport("smtp");
tr.connect("host-name", "user", "some-password");
message.saveChanges();
tr.sendMessage(message, message.getAllRecipients());
tr.close();

Refactoring To Reuse #3

September 25, 2009

#3 Separate Formatting from Core Domain Entities

You may have a core set of classes or services that represent the domain. These classes need to relate to each other cohesively. In the same vein, they should avoid getting too bulky with functionality that isn’t aligned with the business domain. What could they be? Classic examples include data access and remote host connectivity. Also common are formatting logic that is specific to a business channel or view. I talked about decoupling connectivity earlier so in this post I will expand on formatting logic and is a continuation of the earlier post on formatting. Just like any other aspect of your design you can make formatting as complex as you need. The key thing is to encapsulate formatting into its own layer and not let it pollute your core domain entities. This layer might vary by locale (internationalization), distribution/marketing channel (retail branch, online web, kiosk etc.), file format (HTML, PDF, XML), and device or medium (print, web, mobile devices). Even if you have a simple formatting requirement it makes sense often to isolate the logic away from code that does complex calculations and/or executes business decisions.  At the very least, you can create a FormatUtility class to move formatting code there. It would be better to identify the formatting logic and identify an interface to create. You can implement the interface for a specific need and evolve it over time.

Let’s say you have a class that execute business decisions and also contains formatting logic to create data into a text file as a comma separated value (CSV) file. Refactor the file creation out of this class. Look closer on what exactly the formatting is doing. Is it changing values from numeric to text? Is it changing values from non-compliant value to a standard one? Is it doing locale-specific formatting? So, this code may not just be writing to a text file but transforming data and then writing to a file. You want to reuse the transformation logic as well – if you end up writing an XML document instead of a text file you will need this piece of work again. Now, the file creation logic itself can be reused. It may not need to know that a particular process or function is creating it. This will be useful if all your files have standard header records or place specific processing instructions in them for consuming applications. If there isn’t any, don’t refactor this yet. Finally, the text file format may vary – today it is CSV and you might need fixed width. If you have a definite need you can have the file writer take additional configuration information (e.g.  field name and width for a row).

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


Refactoring To Reuse #2

September 5, 2009

#2 Separate Presentation From Domain Entity

Many projects that you undertake might have a presentation component to it – it could be a browser based app, thick client on a desktop, or even a kiosk-type interface. Regardless of specific the presentation technology, you have to ensure that your domain or business logic is effectively decoupled from the user interface code. This is in fact the foundation of the Model View Controller design pattern. You can move business logic in the model layer, presentation logic in the view layer, and the glue code that orchestrates across user actions and domain entities into the controller layer. Often times this separation might not reveal itself in a clean way. In those cases it is important to refactor the code appropriately.

Here is an example – say you have a class named Organization which holds a collection of Units and a collection of Employees. For the sake of integration ease, the Organization class contains a toString() method that generates HTML markup code that formats an Organization object into a neat nested table structure. If you change the way the markup is generated or change rendering output format from HTML to PDF you will end up touching the Organization class. Not a good idea from a reuse standpoint. You want Organization to be about the business entity and nothing else. The fact that it was generated for a web application should be decoupled from the core domain object. You can refactor this class in a number of ways. One way to refactor would be to remove HTML code from the object’s toString() method and move it to a OrganizationFormatter class. This new class could be in a new package structure that is specific to a presentation. If you envision need to support multiple formats you can make OrganizationFormatter an interface and have multiple implementations – a HTMLFormatter, a PDFFormatter, and so on. Based on need a SimpleFactory can be used to return the appropriate formatter at runtime to generate the output. Regardless of the format, you can reuse the Organization class as-is.

Another case where this is needed is when your domain entities make assumptions about the user interface layer. This would require refactoring for enabling reuse as well – will elaborate on this in a future post.

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: