Software Engineering Radio Interview

At JAOO 2006 I gave an interview for Software Engineering Radio. Markus Voelter asked me questions about architecture evaluation, the topic of the talk I gave in the architecture quality track. Here are some of the questions that we covered:

  • Why would you perform an architecture evaluation?
  • When should you perform an architecture evaluation?
  • What are the prerequisites for evaluating an architecture?
  • How does architecture evaluation fit with agile development?

The interview is now available as a podcast; you can also download the slides from the Talks section of this site.I am surprised with the quality of the recording: the bartender was removing clean dishes from the dishwasher clese by. I don’t know how much post-processing was done but all that noise is not distracting. It was distracting while we recorded the interview so I’m glad that it doesn’t interfere with the conversation.

Don’t Miss this QCon Keynote: Democratizing The Cloud

If you’re going to next week’s QCon in London do yourself a favor and attend Erik Meijer’s keynote Democratizing The Cloud. Here’s Erik’s abstract:

The web is rocking the world of developers. Our customers love consistency. They want to have the same rich experience, anywhere, any time, on any device. Our sales people love market share. They want no platform that cannot leverage their web services. We ourselves have embraced agile methods. We want to keep our options open as long as possible and create software incrementally by successive refactorings. This surely sounds like a contradiction, another impossible triangle. As the Dutch artist MC Escher once said “Only those who attempt the absurd will achieve the impossible”. Hence we are trying to stretch the .NET framework to cover the Cloud such that it will become possible to incrementally and seamlessly design, develop, and debug complex distributed applications using your favorite existing and unmodified .NET compiler and deploy these applications anywhere.

Erik will show what consistency means; he will demonstrate how agilty translates into what you do right after you go to the File menu; he will prove how you can keep your options open until just about the very end. So if you’re only planning on attending a single QCon keynote, I strongly recommend Democratizing The Cloud. A few hours ago Erik, Jeff Van Gogh and myself reviewed the demos that he’ll show next week in London. You won’t believe me if I’d tell you, so better see for yourself. Do trust me though that they’re cool–I did work on the one involving validation. Hint: you’ll see p&p’s Enterprise LIbrary like you’ve never seen it before.

The Real Inversion of Control

A recent conversation with my friend and colleague Erik Meijer provided the nudge to finally write about something has been bothering me for some time. So here it goes…The popular view about Inversion of Control (IOC) is that it represents a technique for removing dependencies in object-oriented programs. People immediately think of their favorite dependency injection framework, whatever that may be. That’s nice and well, but is that the real IOC?Consider the following:

  • XML was pitched as a language specifically designed to make parsing easy so developers would not have to write another parser. That has happened allright, very few worry about parsing XML today. However while computers spend less cycles parsing well-formed markup, people crippled their languages with angle brackets, end tags, and a verbose syntax. This in spite the fact that the number of language users > number of XML parsers.
  • Good SOA design recommends building stateless services. Service implementations that follow these guidelines retain nothing from one invocation to another. However while the services do almost nothing to maintain the state of the service conversation, the developers building service consumers picked up the tab. Again, the number of service consumers > the number of services.
  • Web browsers allow people to interact with applications through widgets such as text boxes, radio buttons, check boxes, buttons, and a few more. These widgets are so primitive that they easily map into the native widgets provided by the virtually all contemporary host environments. However while the browser happily renders widgets with consipcuous text UI era traits, developers jumped through many hoops to push the user experience closer to what the platforms have been providing for years. And you guessed it, the number of web applications > the number of browsers.

There are other examples but I’ll stop at 3. The commonality across them is that in each case the software is simpler somewhere because many developers picked up the tab somewhere else. Instead of localizing complexity and putting the machines to work so we could enjoy other, more interesting challenges, the opposite happened. We now have to write in a verbose, ugly-looking language that the software can easily process; manage the state of service conversations so the servers would not bother about it; use plugins and pull lots of strings to give the user experience a face lift so the browsers do minimal processing and rendering; and so on. So consider this other way to look at IOC: the software is in control, and we’re working for it. Darn did I take the blue pill?

Architecture Evaluation in Practice

The slides from my talk on employing state of the art methods to validate software architectures are available (I just didn’t get to it earlier). I gave this talk at the 10th JAOO in Denmark, and then at the patterns & practices summit in Redmond, WA. Though I distilled the talk from experience with ATAM and SAAM, you may find the recommendations useful even if you’re employing other methods. If you’re not familiar with SAAM and ATAM they’re described in the SEI book.

Correlation and Causality

As we wrapped up a group discussion I was reminded about the wonderful discussion of correlation and causality from Freakonomics. How do they differ? When is it one, and when is it the other? Why do people confuse them? The book illustrates eloquently the differences between them. And any mention of causality needs the obligatory reference to the Merovingian: You see there is only one constant. One universal. It is the only real truth. Causality. Action, reaction. Cause and effect.

The Blog-Tag Game

Wojtek blog-tagged me so let’s continue this 21st century pyramid scheme. Here are 5 things you’re not likely to know about me:

  • I have 8 years of classical piano training; I haven’t played the piano in a very long time though.
  • When I was young and foolish I’ve done a bit of rock-climbing.
  • The first framework I’ve ever extended was Digital Research’s CP/M; it came with the source code for the BDOS and a skeleton for the BIOS that provided the 8080 interrupt-driven entry points.
  • My musical preferences span an unusually wide range. For example classical, ethnic, electronic, progressive rock and rock.
  • I like all wheel drive station wagons and dislike motorcycles.

My turn: Greg Wdowiak, Steve Freeman, Paul Brown, Nat Pryce and Brian Foote.

Just shipped: WSSF and WCSF

Two of the projects I’ve been involved with since I started in Microsoft’s p&p group have just shipped:

Both ship in source code and include reference implementations.

If you haven’t heard of software factories my colleagues Jack Greenfield, Keith Short, Steve Cook, Stuart Kent have an excellent book with the same title.

Software Patterns Exhibit Positive Network Effects

I’ve just wrapped up work on a patterns article. While doing the analysis with my co-authors (an co-workers) Ade Miller and Wojtek Kozaczynski I wondered about the connection between software patterns and Metcalfe’s Law.

By the way, if you’re interested in reading about how Metcalfe came up with the ideas that ultimately led to Ethernet read Michael Hiltzik’s book; you will thank me later.

Clearly the more people know about patterns, the better you can communicate with them (since instead of waving hands you would say Decorator, Broker or Service-Oriented Decomposition). Regardless of whether the growth is quadratic or not, the value of patterns increases with the number of people who use them. Stated otherwise, patterns exhibit positive network effects.

Software Patterns Survey

In the patterns & practices (p&p) group at Microsoft we have been using software patterns for several years. I’m working with a couple of colleagues on gauging how the folks employing the guidance coming out of p&p (such as guides, application blocks, software factories and reference implementations) have, are, and will be using software patterns.

To do that we assembled a short survey. If you’ve used patterns I encourage you to take it. If you haven’t used patterns yet but your development tools use patterns one way or another then you could also take it since I’m also interested in your perspective.

You can find the survey Software Patterns: Past, Present, Future here. Thank you in advance for your answers.

A Pattern Language for Versioning

Global Context: Software Change

You are releasing a piece of software (i.e., a software artifact) for others to (re)use as a building block in their software. Reusable code fragments could be delivered as libraries, software components, applications, services, etc. Others find your artifact useful and begin using it. They could use the functions or classes within your library; they assemble applications out of your component(s); they compose your application in their workflows; they build business processes that invoke your service(s).

Once others start reusing your software you discover that you need to modify it. There are instances where modification is not possible. For example, software controlling deep sea sensors or satellite equipment may be out of reach and thus impossible to change, even when its users would like to do so. However nowadays that is the exception rather than the norm. But why change software artifacts that others are using?

One common reason for software change is a bug fix. In spite of stringent testing procedures the probability of finding errors after the software passes quality assurance and ships is not zero. Consequently you (or those using your software) may discover an error in released software. After understanding what is causing the error you modify the code to correct it.

Another driver for change is evolution. The requirements change. For example, new legislation may mandate compliance with a standard. Alternatively there could be a change in the environment. For instance, one of the systems your software is integrating with is being phased out and replaced with a new one. The new systems have slightly different interfaces and your software must change to accommodate them.

Regardless of reason changing software could cause failures—an undesired effect—even when the change fixes an existing error. Consequently the value of the change is context-dependent. For some users the change critical: they cannot operate without it. For others the cost of accommodating the change may be higher than the cost of compensating for it: their software may be counting on the bugs being there, and removing them would entail significant work.

Software change and its impact on those using the software provide the shared context for this pattern language.

Non-breaking Change

Not all types of software change cause failure, having an undesired effect on its users. Sometimes nothing breaks following a change. Ideally all changes would non-breaking. In reality this is the exception rather than the rule, which makes this case uninteresting.

Breaking Change

You released a software artifact. After the release you change it to accommodate a bug fix or a new requirement. You release a new artifact that replaces the old one. However its users start having problems; clearly the shift from the old artifact to the new one is not a NON-BREAKING CHANGE.

Why would a software change cause failure?

A change breaks software when the new artifact (i.e., the software with the change applied) violates one explicit or implicit expectations that the users of, or other software that depends on it, have about the old artifact.

Therefore:

A change that violates an expectation about a software artifact impacts its dependents. User interacting with the artifact may experience unexpected behavior. Likewise, other software using the artifact may fail to integrate. These violations have the potential to cause failure, thus making the change a BREAKING CHANGE.

The expectations could be embodied as contracts or assumptions.

The contracts subject to change when a new artifact replaces an old one could be:

  • Syntactic. For example, the number of arguments required by a method call changes from 2 to 3.
  • Semantic. For example, the amount returned by a service changes from comprising no taxes to including the sales tax.
  • Behavioral. For example, a function call changes from being side-effect free to having side-effects.
  • Quality of service (QoS). For example, a credit check service’s availability changes from 6AM-6PM to 2AM-midnight.

Assumptions can be violated. Garlan [ref] discusses the consequences of dealing with implicit assumptions in the context of composite applications.

BREAKING CHANGEs may keep the users of your software artifact from replacing the old with the new. This impacts maintainability in a negative manner and thus may not be feasible.

Substitutability Check

People use software that is subject to change. Since their correct operation depends on this software they want to assess whether a software update (i.e., replacing an old piece of software such as a library with a new one) would cause their system to break.

Can I substitute the old with the new?

Answering this question entails checking the effect of replacing the old with the new.

The easiest way is to replace the old with the new and see whether the system still works as it should. However if there are problems doing so may have irreversible consequences (e.g., life support system). Even if you can do it, what guarantees do you have that your observations cover all the possible effects of the changes? You need a means of testing for breaking changes that doesn’t impact the existing system/has low risk, and offers great accuracy (i.e., no misses).

Therefore:

Perform a substitutability check to determine whether a software artifact (library, component, service, etc.) can be replaced with a new one without causing a breaking change.

No side-effects translates into performing the check outside the live environment.

There are 2 options, analytical and empirical. High accuracy cannot be achieved in through an empirical check unless the artifact is small and simple. An analytical check requires iterating through all changes and assessing their potential impact. This is impossible without a list of what has changed (i.e., a diff), understanding the changes and their potential interactions and side effects. This is feasible only if you have visibility inside the artifact and understand how it works.

There are several dimensions to performing a SUBSTITUTABILITY CHECK.

One dimension covers who performs the check:

  • Person (manual)
    • Read the changes file and assess impact
    • Perform visual inspection
    • Try it out
    • Perform formal analysis
    • Run test suite
  • Software (automatic)
    • Manager component

Another dimension covers when is the SUBSTITUTABILITY CHECK being performed:

  • At evaluation time. You receive an update and decide whether to substitute (upgrade)
  • At build time. The IDE/compiler must pick between the old and the new library to link against
  • At run time. The runtime must pick between the old and the new dynamic library to load. As with other late binding mechanisms, going this route requires accounting for a failed check at run time.

The SUBSTITUTABILITY CHECK is a procedure that determines whether replacing an old software artifact with a new one will cause BREAKING CHANGEs. The next pattern answers the same question without requiring complex analysis.

[More coming soon so stay tuned]