Software Reuse Quick Tip #32

January 6, 2015

Tip #32 – Fail the build when there is a test failure

Systematic reuse needs automated tests – lots of them. Ensure that your continuous builds don’t keep running when they encounter a failing test – this makes mistakes visible faster and easier to fix. If you are using Maven, you can use the surefire plugin configuration as shown below:


<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <testFailureIgnore>false</testFailureIgnore>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

What I’m Reading & Learning

January 4, 2015

It has been a busy fortnight and have started reading a number of books:

…plus excited to take How to Learn: Powerful mental tools to help you master tough subjects via Coursera.


Value of Service Interfaces

January 4, 2015

Wrote earlier about why interfaces are important and in this post want to elaborate on their advantages for building reusable services. Service interfaces contain only the operation or method definitions and have no implementations. They can be used in a variety of ways:

  • Package service interfaces into a separate artifact to make it easy for client teams to integrate with services without pulling in bulky set of transitive dependencies
  • Bind the interfaces to one or more transport / integration technology via standard Dependency Injection (DI). For example, service interfaces can be integrated with a REST-ful Resource or a EMS listener.
  • Service interfaces can be backed by stub and/or mock implementation for automated unit and regression testing.
  • Service interfaces can be decorated with common cross-cutting concerns to separate them from the implementation. This is the strategy implemented via the Java Dynamic Proxy example.
  • Service interfaces can be implemented as a proxy to a remote implementation. For example, the client invokes the functionality via the interface but the runtime implementation makes a call to a server side API. This is useful if your teams need the flexibility to swap local / remote implementations depending on performance / dependency management related requirements

Make Services Fault Tolerant & Supportable for Production Use

January 3, 2015

A lot of teams are building services for clients both internal and external to your organization. Typically, there is quite a bit of focus on succeeding from a functional sense – did we get the key requirements addressed? does it cover the plethora of rules across markets / jurisdictions? and so on. Some of the more experienced teams, consider the non-functional aspects as well – e.g. logging, auditing, exception handling, metrics, etc. and I talked about the value of service mediation for addressing these in an earlier post.

There is an expanded set of capabilities that are also necessary when addressing non-functional requirements – those that are very relevant specially when your service grows in popularity and usage. They fall under two categories: operational agility and fault-tolerance.  Here are a few candidate capabilities in both these categories:

Operational Agility / Supportability:

  • Ability to enable / disable both services and operations within a service
  • Ability to provision additional service instances based on demand (elastic scaling)
  • Maintenance APIs for managing resources (reset connection pool, individual connections, clear cached data, etc.)
  • Ability to view Service APIs that are breaching and ones that are the risk of breaching operational SLAs
  • Model and detect out of band behavior with respect to resource consumption, transaction volumes, usage trends during a time period etc.

Fault Tolerance:

  • Failing fast when there is no point executing operations partially
  • Ability to detect denial of service attacks from malicious clients
  • Ability to gracefully handle unexpected usage spikes via load shedding, re-balancing, deferring non-critical tasks, etc.
  • Detecting failures that impact individual operations as well as services as a whole
  • Dealing with unavailable downstream dependencies
  • Leveraging time outs when integrating with one or more dependencies
  • Automatically recovering from component failures

In future posts, I will expand on each of these topics covering both design and implementation strategies. It is also important to point out that both these aspects are heavily interconnected and influence each other.


Making The Most of Projects To Drive Systematic Reuse

January 2, 2015

Systematic reuse takes conscious, disciplined effort – question is – where are the systematic reuse opportunities? how can we maximize these opportunities? – it may or may not surprise you that there is rarely a special, designated ‘project’ to achieve reuse or build a reusable API. Teams are busy and they want to solve tangible problems – they work on projects more often than reusable libraries and services. Some reuse advocates lament this situtation – they wish the organization supports systematic reuse with a protected budget, appropriate team members, and the organizational mandate to enforce reuse APIs and standards. I used to wish this too and I was wrong – way off the mark :-)

Now for the good news – the great thing about the lack of a reuse budget is that, you can focus on the more important thing: achieving business objectives either by saving costs, creating new revenue lines, and reducing uncessary risk. Projects have the necessary business objectives baked into them – that’s why they are funded, resourced, executed, and tracked. Finally, they have an important constraint: time. Projects have deadlines. Schedule risk is a key one with reuse efforts and having a project deadline ensures the asset is going to be useful and relevant to the project at hand. Below are a few tips to get the maximum out of projects:

  • Review the requirements – whether it is a set of tickets, a sprint plan, or a formal document – review and categorize requirements into ones that are specific to the project, common to the product line, and common across projects.
  • Ensure you are engaged with the development team throughout the project lifecycle – reviewing and identifying opportunities for identifying, leveraging, and refactoring code. Very often, reviews are done long after development is complete with an impending deadline. This leaves little room for introspection, refactoring, or improvements to the codebase.
  • Identify existing components and services that are potential reuse candidates – most importantly, identify assets that are readily reusable (even if they are part of an existing project codebase), ones that need minor refactoring, and ones that need substantial refactoring / development. Minor refactorings and enhancements which can be done in parallel while users are testing / verifying functionality is one of many possibilities.
  • Insist on development teams using agreed upon interfaces for reuse-eligible functionality. Dev teams can either create a bespoke implementation, fork off an existing implementation, or leverage a reusable API.  However, none of this is possible if the projects use bespoke classes / APIs. Interfaces give your team the freedom and pluggability to swap implementations, evolve asset maturity, and ultimately carve code off the project to seed and grow a reusable API. It doesn’t matter if the interface is implemented by a local component, a remote service, with or without persistence, etc. – the implementation will depend on performance and resiliency characteristics in addition to functional needs.

Targeting Quick Wins And Sustaining Momentum

September 7, 2014

Systematic reuse initiatives don’t have to be big-bang events preceded by a lot of noise. It can be done quietly – project by project with a resolute focus on getting targeted wins. As I’ve blogged before, the key is discipline – not technology. The most fundamental question to ask your teams – do they have the basics in place? Specifically:

  1. How do they go from requirements to design – is there a set of known patterns and frameworks that will anchor the design? If so, ensure every project is aware of these and when appropriate leverages them in the design.
  2. Are there trust issues with the software being produced by the sister teams? Before you dismiss this as a ‘soft’ issue – remember, your developers and development leads are human and need healthy social relationships at work before they let others influence them. Influence translates to systematic reuse – not occasional but project after project. 
  3. What happens in cases where a project develops a lot of potentially reusable code – who knows about their existence outside the immediate development team? who is going to be accountable for appropriate teams to leverage this work? If you don’t know the answers – don’t be surprised that your software solutions are siloed. No getting around Conway’s Law
  4. Do you send project updates and accomplishments like many development teams? Most of the time, the target audience is management and the intended message is to gloat how successful the delivery was. Celebrate and reward your teams but also take the time to reflect on two additional themes: did we best utilize the organization’s existing software assets – that includes prior requirements, component libraries, frameworks, services, and patterns? and did we contribute back to the organization’s repository of shared software assets? These aren’t tough questions to ask but you will be surprised by the answers!
  5. What are the biggest roadblocks to sharing software assets? Don’t assume it’s communication or organization structure or code quality or learning curve or integration ease (or all of them!). Go to the scene of action – spend time pair programming with developers to empathize their circumstances. Watch them struggle to get something to play well in their IDE or plain compile or execute with a myriad tweaks. Don’t assume – collect evidence and focus your improvement efforts on making their lives better.

Think Hard About Conway’s Law

August 24, 2014

Was reading Adrian Cockcroft’s interview on InfoQ recently – where he talks about MicroServices and DevOps, and whole range of topics. A particular point about changing the team’s culture directly applies to reuse. 

I quote from one of his answers: “…is it Conways law?… what’s the organization…? Basically the law that says the communication structure of an organization will be reflected in the code. So you set up the … you decide what structure you want your code to have and you make the organization look like that;”

I am sure you have been in situations where you wish: the code for a reuse candidate was in a common shared source control repository, the components were adopting compatible technologies, that there was clear separation of concerns, and most important, there was a true culture of sharing and systematic reuse across projects. 

This is so true that it got me thinking – how often do we want something to happen – be it collaboration, co-creation, systematic reuse – and yet we run into organizational roadblocks? Lack of core competencies – too many people solving the same problem in a sub-standard fashion, conflicting priorities, inadequate knowledge sharing of not just code but more fundamentally: key requirements, lack of human / monetary / infrastructure resources, etc.

Instead of negotiating constantly across multiple teams – all looking to meet several success criteria – have you thought of organizing them by the outcomes you seek? If you want shared software assets, you need to foster sharing organically, through the organizational interactions that happen every single day. Who reports to who, who is held accountable for what, – the nuts and bolts of responsibility and accountability have to be thought through for the shared software assets you aspire to create and reuse. 

It’s easy to get a single flash in the pan reuse success story – it’s much harder to institutionalize it across teams and projects. Have you got the responsibilities in the team defined in terms of the shared software assets you envision? More often than not – we tend to look for magic bullets in terms of tools, technologies, trends, fads, and yet – systematic reuse is fundamentally about the delicate dance of interactions, trade-offs, and decisions that development teams have to make in the midst of competitive pressures and harsh deadlines. Focus on the form and structure and reuse will follow. If you aren’t getting reuse, think hard about Conway’s Law – the state of your software won’t lie – it won’t hesitate to show up the healthy or not so healthy nature of team interactions, incentives, and priorities that are alive and thrive on the ground. 

 


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: