Thursday, December 6, 2012

Examples and Objects

The most successful and fun project I have been part of developed a network simulator for operator training. We had a great team and freedom to work how we wanted, but another key to success was the domain model. The analyst drew object diagrams to explain to the programmers and testers how a network topology could be, for instance like this:


This may look simple, but these diagrams explained a lot to us. We used them to discuss what should happen in different scenarios, such as what should happen when a Trunk is connected to another Port. Then we implemented these scenarios as unit tests. This resulted in a robust implementation with few bugs.

But in most projects, we don't have anything like this. In one project I spent several days trying to understand how a trading system worked. I had the domain model and database schema, but it was not clear when these objects were created, updated and deleted in the database. I read thousands of lines of code and run the program in a debugger, but this didn't tell me when the behavior was executed. Finally, I found out, and I drew some diagrams. When I presented this to the project manager, analyst, testers and other developers, it was a revelation to people that had worked on that system for years. They finally understood the internal behavior of their application. This behavior was certainly clear to the original designers of the application, but it was not documented anywhere. The result was that new programmers like myself struggled to understand the application logic. This happens all the time in our industry. It is frustrating for developers and costly for companies.

Developers need some documentation; the code is not enough. But what is the best format for this documentation? We don't need thick Word documents. A few examples of domain objects can take us very far. And the great thing about domain objects is that they can be discussed with users, analysts and testers, so that the whole team get a shared understanding of the behavior of the application.

We can take a few key examples of the system behavior and show which domain objects are needed in those examples and which objects are created, deleted and updated. This gives a high-level view of the internal behavior of the application.

The example below shows one way to do this.

Given the following objects:


When the user enters the following:


Then the application should give the following output:
  • Total hours: 39

And the following objects should be created:



Examples connected to domain objects give a high-level view of what the application is doing. It is suitable for discussions with users, analysts, developers and testers, and it is great documentation for future developers.

The example is ready to test and the format is well suited for test automation. By using this specification as input to a test automation tool, you get high-quality tests that focus on the domain logic instead of brittle user interface testing. This kind of tests are great input to programmers, because they are directly connected to the specification and they contain the details that the programmers need. (I have written about specification by example here.)

In the example above, I used the terms Given, When and Then to show how this method can be compared to Behavior Driven Development (BDD). The difference is that BDD uses 3 steps (Given, When and Then), while this method uses 4: Initial objects, Input, Output and Result objects. More importantly, the present method uses domain objects more explicitly than BDD. This gives a strong connection between the specification (examples) and the object model. When this is combined with automatic tests, the specification, code and tests will be tightly integrated and kept consistent with each other. The domain objects become the glue that binds everything together. 

Tool Support

I am working on a tool where a specification by example is connected to objects and used for automatic testing. The examples and objects are written a wiki-like text format. This is used to generate HTML documentation. The domain logic is then implemented in Groovy and tested against the specification with JUnit.

Thursday, November 29, 2012

Writing Better Requirements with Examples and Screen Sketches

We were agile, we had a Scrum master, we had standup-meetings, we had unit tests, we worked iteratively and met the product owner regularly. We did everything right, except the requirements. When we were almost ready to launch, we suddenly understood that we had missed a critical piece of functionality; namely the complex pricing model. The product owner thought we knew how this should work, but we didn't. This was not a feature that could just be patched onto the application in the end, it took several weeks of restructuring. We might blame the product owner for not communicating this clearly, but we were the software professionals. It's our responsibility to find out what our customers want.

Examples

What could we have done to avoid this embarrassment? Should we have spent the first month of the project writing requirements? No, I don't think that's the solution. That might have helped, but it would have cost too much.

There is a much simpler thing we could have done. In one word: Examples. If we had given the product owner an example of how we would calculate the price early in the project, the product owner would immediately have pointed out the misunderstanding and explained how to calculate the price correctly. This would have enabled us to make a better plan and implement that feature effectively.

Examples is a way to write useful requirements without too much effort. They are easy to understand by all parties involved: Users, project managers, analysts, developers, UI designers and testers. Examples reduce misunderstanding and thereby reduce risk and save cost.

Another advantage of examples is that they can be tested automatically. This is not possible with traditional requirements specifications. Then, you first write the general requirements, then test specifications and perhaps try to automate the tests. But examples are tests, and if they are written in an adequate format, they can be used by testing tools. This saves manual work with testing, ensures that the implementation and specification are consistent, and helps developers to focus.

Screen sketches

What is the best format to write examples? What does the user understand best? The user interface, of course! That's why prototypes are so useful. To quote Jakob Nielsen:

Whatever you do, at least promise me this: Don't just implement feature requests from "user representatives" or "business analysts." The most common way to get usability wrong is to listen to what users say rather than actually watching what they do. Requirement specifications are always wrong. You must prototype the requirements quickly and show users something concrete to find out what they really need. (www.useit.com)

A problem with prototypes is that they take a while to build. Writing requirements should be quick and easy so you can do it together in a workshop. Also, prototypes are not suitable for automatic testing.

Instead, we can specify examples as user interface sketches. This is not user interface design, but a user interface specification. The sketches don't need fancy widgets, it suffices with labels, text fields, tables, check boxes and selection boxes, so that input and output values can be displayed. At this stage, we only need to specify what the user can do, not how.

For instance, an abstract requirement like "The employees report worked hours every week," may seem obvious to the customer, but it leaves lot of room for interpretation. Instead, we can give a concrete example like this:


This example is much easier to understand than the abstract requirement. The customer can easily spot mistakes and fix them. For instance, the customer may point out that they can work on multiple projects at the same time and give a better example like this:


In my opinion, this is as clear as it gets. It reveals a lot of questions for further discussion, like who defines the projects, can the employees work on weekends, what happens if the employee works more or less than 40 hours in a week, etc. Discussing these questions with the customers before implementation can easily save an iteration or two in the project.

Tool support

Screen sketches are easy to read, but are they also easy to write and suitable for test automation? It is fairly easy to make a tool that lets you design screen sketches; either a GUI builder, or simply writing them in a text format. This data can then be used by a tool to test the application. I have started on such a tool where you can write wiki-like text and generate HTML pages with screen sketches. The examples can then be used for automatic testing. You can read more about the tool and try it here.

Conclusion

Examples are useful for communicating with customers, as specification for programmers and UI designers and as test specification for testers. Ideally, all these groups should discuss the examples in detail together with the customer and analyst before an iteration. The programmers will then have all the details they need, the testers will know what to test, the customers will get the right product, and everybody's happier.

Friday, November 23, 2012

The Future of Programming

The problem with abstractions

Programmers are experts in abstract thinking. To program is to generalize: A method is a general specification of different execution paths. A class is a general specification of objects. A superclass is a generalization of several classes.

Although our minds are capable of abstract thinking, concrete thinking is more natural, and concrete examples are the foundation for abstractions. For instance, how do you teach children what a car is? You don't give a definition like: 'A car is a wheeled motor vehicle used for transporting passengers.' Instead, you point at a car and say: 'Look, a car!' After seeing a few cars, the child understands what a car is.


Notice what I just did! I started with a general principle and then gave an example. Which part of the paragraph above is easier to understand, the first sentence (general) or the rest (example)?

Einstein said that examples is not another way to teach, it is the only way to teach. It is easier to start with a few examples and then generalize than the other way around. If you start with an abstract description, you will often try to comprehend it by visualizing an example in your head.

The problem with text

Another point is that children understand better what they see than what they hear. Or as they say, children do what you do, not what you say. This is not only true for children. We understand what we sense in fractions of a second, but words must be analyzed before they give meaning. This doesn't take long for simple sentences, but it can take hours, days or months to understand source code of any significant size. Some source code is actually incomprehensible and nobody dares to touch it.

What does this have to do with programming?

As programmers, we are highly skilled in abstract thinking and textual programming languages, but when the code becomes too complex, we try to comprehend it by imagining its behavior. And when it becomes too hard to imagine the actual execution by reading the abstract code, we log what happens or run the code in a debugger. Logs and debuggers are not abstract. They give concrete descriptions of what is actually happening. They give information on method calls, object instances and variable values. This concrete information is much easier to understand than the abstract code.

We can move programming closer to how the mind works by using examples as part of the implementation. Unit testing is one way to do this, because unit tests are examples of what the code can do. There is also a growing movement for using examples as requirements. This improves the communication between users, analysts, programmers and testers. These examples can be automatically tested to connect them to the code.

Objects are examples of classes

So what is the best way to specify examples? I think that the most effective formats are user interface sketches and objects. The user interface is the best way to explain the external behavior of a program, and objects can be used to describe the internal behavior. I am not talking about technical objects that is part of the infrastructure, but domain objects that the end user understands.

Objects can be specified as text, in tables or in diagrams. Diagrams are easiest to understand, but they can be cumbersome to draw and edit.

Here is an example of an object diagram:
It is pretty obvious what this means.

If Lars sells his car to John, the objects should be changed like this:
Alternatively, the same information can be specified in tables or as text.

Modeling examples as objects is an effective way to build a domain model. This makes the examples consistent with each other and helps to reveal details and missing functionality. They are great as specification for programmers, because they are specific and contain a lot of details. And they can be automatically tested easily.

Tool Support

I believe that using examples and objects is the future of programming because it is closer to how our mind works.

I have started on a tool where you can write a specification by examples with screen sketches and objects. The application is then implemented in Groovy; a dynamic language that runs on the Java platform. The tool can test the examples to verify the program. Read more about the tool and try it out here!

Stay posted!

Thursday, November 22, 2012

Object cases tool released

I just released our new tool. It supports specification by example, object modeling, automatic testing and implementation in Groovy. The tool is open source. Here it is.

Stay tuned!