Modeling in an Agile Context

Alan Cameron Wills
Microsoft Corp.

 

March 2010

 

Summary: Models can help you explore existing code and discuss new designs; clarify users’ needs and define tests; and be used to generate some of the code. This article shows how working with models will help you in an agile project.

 

Introduction

Modeling is a valuable tool for an agile team. A model is a view of a chosen aspect of your application, such as the sequence of interactions among components; the business activities of users; the language of user concepts and relationships that is ubiquitous in the design; or the dependencies among different parts of the code.

Models are developed along with your stories and code throughout your project. You use modeling as an additional tool to complement good practice in agile development.

Models can help you:

  • Explore existing code. Generated diagrams of the interactions and dependencies in the existing code help you understand its structure, discuss proposed changes, estimate costs, and create tests to drive the development.
  • Understand users’ needs more clearly.  Agile practice requires early and frequent demonstration of working software to ensure that the actual needs of users are met. In addition, models of activities and concepts in the user world help you raise important questions at an early stage in each iteration.
  • Refactor code frequently without loss of structure. A well-planned incremental product backlog results in the code being repeatedly refactored and extended. Unit tests protect against the introduction of bugs, but not against misplaced methods and dependencies that gradually make the code difficult to change. Using layer models, you can define the expected dependencies in your code and validate the code against the model at every check-in.
  • Discuss and communicate about your code. Models make it easy to visualize and discuss the components, interactions, and design patterns in the code. This is especially important in a geographically dispersed team. 
  • Define tests. Models provide a reliable framework for a comprehensive set of acceptance or component tests. 
  • Generate code. You can respond very rapidly and reliably to changes in user requirements by generating code from a model. This is particularly important for product lines of similar applications, as well as for generating frequently used patterns.

This article illustrates each of these uses. The tools that are discussed are available in Microsoft Visual Studio 2010 Ultimate.

Exploring Existing Applications

Many—perhaps most—software projects update an existing application. Often, the original developers have moved on, so that the first task is to find your way around the code. You will want to identify the places in which changes are required, and then find out how far the consequences of the changes will propagate, so that you can estimate costs. As an agile developer, you will also want to construct unit tests for the existing code to keep it stable through your updates. To do so, you will need to identify the functions of each object and understand how they interact.

Visual Studio’s Architecture Explorer is a versatile browser that can navigate many relationships, such as containment, calling, and dependency among elements of your code. You can build up diagrams of the areas in which you are most interested. On the diagram, you can group elements together, filter what is visible by various criteria, and highlight “bad smells” such as dependency loops. You can also double-click a node to see its code (see Figure 1).


Figure 1. Dependency graph of code, in which each node can be expanded (Click on the picture for a larger image)

 

After a succession of hurried changes by different developers, the structure might be somewhat obscure. Even well-written code can be difficult to follow, as control bounces among different objects with well-separated responsibilities.

However, a clear overview is easy to obtain. Place the cursor on a method, and select Generate Sequence Diagram. The method’s calls and their calls will be laid out in a diagram, to whatever depth you desire. Now, you can see what is happening and can edit the diagram to discuss different proposals for improvement (see Figure 2).


Figure 2. Sequence diagram, generated from code (Click on the picture for a larger image)

 

Stabilizing Architecture Through Many Increments

Agile projects minimize risk by developing in many small increments, integrating and testing the application after each increment. Automated unit tests are very important to avoid building up bugs. However, although these tests catch functional errors, they do not verify the structure of the application.

A  well-structured graph of dependencies among the parts of an application is essential to an agile development, as it allows the program to be changed easily when the users’ needs change. Through multiple increments, however, it is easy for developers to lose sight of the original design. A method that is placed in an inappropriate class will often work, but at the same time introduce dependencies that make it more difficult to adapt the application at a later date. Over time, this architectural debt reduces the adaptability of an application to requirements that have changed and can shorten the lifetime of the product. Validation against layer diagrams helps the team avoid this kind of mistake.

A  layer diagram shows the major parts of the application and the dependencies among them. It leaves out the details of how the parts work and how they interact, and it shows the same information as the traditional software-block diagram (see Figure 3).

Figure 3. Application structure in layer diagram

 

Layer diagrams are also a powerful tool for ensuring that the code actually conforms to the architecture—and that it stays that way. When you draw a layer diagram in Visual Studio, you can assign groups of classes from your code to each layer. You can then run a validation tool that verifies that the dependencies in the code actually follow the arrows that you have drawn in the model.

Layer validation can be added to your check-in tests and continuous integration build. This means that you can ensure that future changes always conform to the architecture; no one can inadvertently introduce new dependencies among the major parts, without first updating the layer model.

Models of Users’ Needs

Agile teams work closely with business stakeholders throughout the project to ensure that their needs are correctly understood and that changes during the project can be taken into account. Working software is demonstrated at the end of each iteration. Part of the motivation for this practice is that user stories are usually ambiguous and inconsistent, especially if the customer’s business domain

is unfamiliar to the development team. Nothing disambiguates requirements like working code.

Working with a model of users’ needs can also help expose important issues—often, within the first day of discussion. Models can be very effective at describing complex relationships and behaviors— clarifying ambiguities and revealing inconsistencies. Therefore, they are a very effective complement to user stories.

A domain class diagram is a central part of a requirements model. It describes the principal concepts and relationships in the world of the users (see Figure 4).


Figure 4. Concepts and relationships in language of users (Click on the picture for a larger image)

 

Notice that the example in Figure 4 is not directly a class diagram of the software solution, which might represent these relationships in different ways. Instead, it presents a vocabulary with which you can write user stories:

The customer chooses a Menu from which to construct an Order, and then creates Order Items in the Order by selecting MenuItems from the Menu.

Misunderstandings about user requirements can frequently be traced to misunderstandings about the detailed meanings of words. For example, the difference between an item on an order and an item on a menu can be unclear without the diagram. When requirements are being discussed with business stakeholders, it is important to expose those differences.

Creation of the model helps you ask questions of your business customers that you might not otherwise have asked until much later in development. Standard techniques include asking about the cardinalities (“Can a Menu Item appear on more than one Menu?”) and about loops in the diagram (“In any Order, are all the Items from the same Menu?”). The answers to this type of question can be added as annotations to the diagram.

Dynamic View

Another useful aspect of a business model is the activity diagram. Once again, the objective here is to describe what users see, instead of anything that happens inside your software (see Figure 5).

Figure 5. Workflow in activity diagram

 

Activity and class diagrams are two views of one model, describing dynamic and static aspects of user stories. One can be described in terms of the other: The Choose Menu action represents what the user does in creating an Order against a chosen Menu; the Select MenuItem action represents the user creating an Order Item that specifies a quantity of a selected Menu Item; and the Pay action reminds us that we have not yet described the concept of prices and, thus, prompts further questions to business customers.

Conversely, asking what instantiates or changes each class and relationship on the class diagram prompts further questions to clarify the requirements (for example: “How do Menus and Menu Items come into existence? Do restaurants have their own user interface to update these items?”).

Spike or Asset?

Is a requirements model just a sketch that you throw away after the first iteration? We recommend not, for several reasons:

  • At the start of each iteration, you revisit and elaborate the stories that will be developed in that iteration. To help with this, you can add more detail to the corresponding aspects of the requirements model.
  • Much of the value of a business model is in its role as a glossary of terms. The value is lost if the document is discarded. It is useful to build it up through the project—relating new or more detailed concepts to the basic ones.
  • Requirements models are the basis of system tests and, in some cases, can be used to generate part of the code.

Requirements Models and System Tests

You can use a requirements model as a basis for system tests—making a clear relationship between the tests and the requirements.

When the requirements change, the relationship helps you update the tests quickly and correctly. This ensures that the system meets the new requirements. In Visual Studio Team System, tests are represented as “work items”—that is, records in the shared project-management system. Furthermore, you can link any element in a UML model to any work item, such as a test. When any part of the model changes, the model will help you locate the tests that are related to it.

The structure of the model helps you ensure that you have written tests for each important aspect. You should write tests to cover each user story. However, you can verify that all aspects have been covered by crosschecking with the model:

  • There should be at least one test that involves the construction of each type or association (such as Menu Item and Order Item) and at least one test that involves their destruction.
  • There should be at least one test for each action in the business-activity diagrams.
  • There are some tools such as Microsoft Spec Explorer that can accept a state model and produce tests from it automatically.
  • Tests should verify that the static constraints of the model are always satisfied—for example, that the items on an order are all from the same menu. 
  • You should base test definitions—whether manual or automated— on the requirement types (such as Order and Menu).

This last practice helps you keep the tests more accurately in step with requirements changes. For manual tests, adhere to the vocabulary of the requirements model in your test scripts.

For automated tests, use the requirements class diagrams as the basis for your test code, and create accessor and updater functions to link the requirement model to the implementation code. For example, in your requirements model, you might have LibraryDVD and LibraryMember classes, an optional onHireTo association between them, and a HireDVD use case whose definition simply states that an onHireTo link must be established between the DVD and the library member. However, the implementation is much more complex; this information is represented in several database relations; and performing the use case requires several steps in the Web site, as well as the warehousing and accounting subsystems.

To test the use case in terms of the requirements model, implement an API that retrieves the onHireTo relation from its complex internal representation and can simulate the steps of the use case on the various subsystems. Then, you can run a test of the use case by checking that a DVD does not have the onHireTo link, invoking the HireDVD use-case simulation, and checking that the DVD and library member are now linked by the onHireTo relation.

In this way, the requirements model is the central definition of the tests. Visual Studio allows you to generate code from models, so that you can use the model to generate the skeleton of the tests.

Design Models

In a large project, several different parts of the application are generated in parallel. Continuous integration verifies that they work together. To help bring this about, it is important for the developers to understand the interfaces of each component and how they fit together. For this purpose, use:

  • Component diagrams to show the components and their interfaces, and how they are wired together to make larger components.

    A component can be anything from an individual object to a substantial system, and the connectors between them can represent method calls, event signals, Web service calls, or even motorcycle couriers.

  • Activity diagrams, divided into swim lanes for each component part and external actor—showing how the components share the work. 
  • Interaction diagrams, with a lifeline for each component part. 
  • Class diagrams to describe the types that are visible at the interfaces of the components and that are transmitted among components.

In UML component diagrams, you can show required interfaces as well as provided interfaces (see Figure 6). This allows you to represent a component that is separable from the components that use it as well as the components that it uses. A clear understanding of this separation is important for the developers to be able to test the component in isolation—using mock objects to plug-in to the required interfaces.


Figure 6. Component diagram showing parts and their wiring (Click on the picture for a larger image)

 

Just as with the requirements models, models of the components should be no more detailed than what is useful at each iteration.

Models are also useful to help describe recurrent patterns. Just as the Observer pattern (for example) is applicable to a wide variety of applications, many projects find configurations of objects that are useful for their particular purposes.

Product Planning

In agile parlance, the product backlog is the list of stories that will be implemented in each iteration. Each iteration delivers a working (although limited) system—representing a slice through the functionality of the system and touching on more than one user action. A user action (such as selecting from the menu) can be introduced in a basic form in one iteration, and then extended in successive iterations. Each iteration can introduce several new actions or extensions. This approach assures us at an early stage that the design fits together, and allows time for stakeholder feedback to be accommodated.

Using Visual Studio Team System, you can record stories and other work items. Developers update work-item states as development progresses, and you can obtain burn-down charts and other progress reports.

You can also link work items to elements on the model—for example use cases or activities—so that you can keep track of the state of development of each story.

A use-case diagram is useful to help envisage and discuss the product backlog. In this interpretation, rectangular subsystem shapes are used to represent successive iterations in the plan. The use-case ellipses represent user actions or their extensions that are to be implemented in each iteration (see Figure 7 on page 43).

The diagram in Figure 7 shows clearly the dependencies between user stories, so that you can see easily whether moving a story to a different iteration will mean that you have to move another story that is dependent on it. The plan shows clearly how the stories are grouped and when they will be delivered.


Figure 7. Using use-case diagram to plan iterations (Click on the picture for a larger image)

 

You can also link sets of tests to the appropriate use-case shapes. These tests effectively define the meaning of each use case: The use case has been implemented when its tests pass.

Generating Code from Models

From a model, you can generate program code, schemas, documents, resources, and other artifacts of any kind. In the basic method, you write text templates that interrogate the model by using the UML API. A more specialized toolkit is available in the Visual Studio 2010 Architecture Power Tools. Models usually generate only parts of your code, so that it is essential to use techniques such as partial classes that allow you to mix handwritten code with code that is generated from one or more models. (Never edit generated code! You want to be able to update the model and, thereby, update the code.)

Code generation allows you to respond to requirements changes rapidly, because the model is closer to how the requirements are expressed.

Here are some examples:

  • Product lines—Fabrikam, Inc., builds and installs airport baggage-handling systems. Much of the software is very similar between one installation and the next, but the software configuration depends on what bag-handling machinery is installed and how these parts are interconnected by conveyor belts. At the beginning of a contract, Fabrikam’s team discusses the requirements with the airport management and captures the conveyor-belt plan by using a UML activity diagram. From this model, the team generates configuration files, program code, and user guides. They complete the work by manual additions and adjustments to the code. As they gain experience from one job to the next, they extend the scope of the generated material. 
  • Patterns—The developers in Contoso, Ltd., often build Web sites. They design the navigation scheme by using UML class diagrams, in which classes and associations represent Web pages and navigation links. Much of the Web-site code can be generated. Each Web page corresponds to several classes and resource-file entries—conforming to a uniform pattern. The result is more reliable and flexible than handwritten code.
  • Schemas—Humongous Insurance has thousands of systems worldwide. These systems use different databases, languages, and interfaces. The central architecture team publishes models of business concepts and processes internally. The diagrams make it easy to discuss the designs. From these models, local teams can generate parts of their database and XML schemas, C# declarations, and so on.

Custom Modeling Languages

In the preceding examples, each company has a very specialized use for its models. Although a baggage track can be represented by using an activity diagram, a proper baggage-track notation would be much better. Visual Studio supports two alternative approaches:

  • Customize a UML diagram by using stereotypes. Stereotypes allow you to differentiate different types of element—for example, to distinguish check-in desks from X-ray stations—and allow you to record additional attribute values in each element. 
  • Design your own domain-specific language (DSL)If. you do a lot of work in the target domain, the additional effort might well be worth the more specific adaptation to your needs.

The Visual Studio SDK also allows you to design menu commands, validation tests, and toolbox items for both of these types of model. You can also build Visual Studio extensions that integrate diagrams together and couple them to external resources such as databases.

Conclusion

Models work well in an agile context. They are not about big upfront design, but are developed along with your stories and code. Models can help you explore and refactor an existing system, clarify users’ needs at an early stage, and discuss and communicate many aspects of your code. They can act as a solid framework for tests to help ensure that everything is covered. You can specialize the Visual Studio modeling tools to your own needs, including the ability to generate code from them—which can make your response to requirements changes very agile, indeed.

Acknowledgments

Thanks to David Trowbridge, Jamie Cool, Steve Cook, Peter Provost, Stuart Kent, and Cameron Skinner.

Further Reading

About the Author

Alan Cameron Wills (alan.wills@microsoft.com) is a programming writer in Microsoft, who works on modeling and process-support tools. He has been a developer on the Domain-Specific Language and process-guidance teams. Before joining Microsoft, Alan was a consultant in UML and agile development.

Clash of the Illuminati

Michael G. Miller

 

Enterprise-architecture and system-development groups often act as Illuminati (that is, groups that claiming to have received special enlightenment) and believe that their particular approach to systems development is the only correct one. Often, these groups clash because their views toward development are polar opposites.

Enterprise architecture takes a long-term view towards software development—concentrating on operations stability and ensuring that software development adheres to enterprise architectures and standards. Software-development project groups take a short-term view—with a focus on speedy software completion and implementation.

These groups clash by using gates that are placed at the end of software-development steps, to curtail their variance from existing architectures and standards. However, a better approach to software can be applied that benefits both parties.

Instead of gates at the end of each development step, perhaps an “accelerator” can be placed at the beginning of each step by reviewing the system-development efforts with existing enterprise architectures to accelerate development through the reuse of existing architecture components, such as existing process and data models, or entity definitions and data formats. In this approach, software development avoids “reinventing the wheel” through the development process; and enterprise architecture enters at the beginning of each step, instead of at the end.

This “enlightened approach” puts enterprise architecture in the position of a “swim coach” who provides techniques to speed development efforts, instead of a “border guard” who inhibits development efforts from moving to the next step. This approach provides a “win-win” for architects, developers, and (ultimately) the end customer by reducing costs, speeding development, and enhancing the quality of final deliverables that are more efficiently and effectively aligned to existing enterprise architectures.

In his book Out of the Crisis: Quality, Productivity, and CompetitivePosition (Cambridge, MA: MIT Press, 1982), W. Edwards Deming states that we should “cease dependence on inspection to achieve quality.

Eliminate the need for inspection on a mass basis by building quality into the product in the first place.” We can build quality into the systems-development process by introducing enterprise architecture at the start of each step, instead of at the end.

This approach provides a:

  • Better way to manage the relationship between enterprise architects and software developers. 
  • Pain reliever to development-step walkthroughs and gates— speeding passage to the next development step.
  • “Win-win” approach to accelerate deliverables through each software-development life-cycle step and enhance overall system quality.

For more information on this approach, see the author’s enterprise-architecture blog at https://1enterprisearchitect.wordpress.com/.


Michael G. Miller ( 1enterprisearchitect@gmail.com) is an Enterprise Architect consultant who is now concentrating on Mobile Enterprise Architecture. He has over 30 years IT experience and holds Master’s Degrees in Business Administration, Project Management, Telecommunication Management, and Information Systems Management.

Combining Client and Provider Methodologies in Custom Software Development

Henry Rosales-Parra

 

The situation: You are part of a custom software-development company that is using a certain methodology to deliver your projects. On the other hand, your client has its own in-house software-development methodology that is tightly coupled with a project-management discipline, and without a chance of being overlooked. How can you cope with this situation?

Here are some useful tips:

  • Try to negotiate adjustments to make certain methodology components flexible on both endsSit. down with your client, and conduct a review of the procedures. Sometimes, you can gain additional know-how from your client and introduce new elements or changes into your methodology. Be sure that the resultant set of parts of the methodology is known and approved by both parties. 
  • Follow a simple right-hand rule. Allow changes in your methodology if they make the requirements clearer, ease technical decisions, decrease development times, or increase the quality of the software. Take into account how changes in methodology affect your budget. 
  • Involve the client in architectural decisions, but only if necessary. First, be sure that you have all functional requirements and technical information; then, make the appropriate decisions. If the client is required to be part of the architectural decisions, anyway, do not forget that your mission is to provide solutions; therefore, come up with well-studied options.
  • Do not fall into the excessive-documentation trap. Avoidallowing your project to become a “documentation project.” Allow documents to be a foundation, instead of an objective. 
  • Do not allow any quality process to be removed. These are not optional. Allow the client to take part in testing procedures, but preferably with the purpose of checking that all requirements are covered. Usually, allowing the client to be involved in “bug hunting” is counterproductive if the process is not well-understood as part of a stabilization phase. 
  • Do you use an agile methodology, but your client counts on a more formal approach? Let the formal envisioning and design-phase deliverables be the input of your agile-development sessions. In the development phase, introduce the concept of “requirements micro-segmentation”: Convert groups of formal requirements into mini agile projects—for example, creating a chain of fully built components/modules and conducting additional testing sessions at the end of one or more blocks of requirements. Performance of one or more deployment sessions would depend on the completeness of each developed block.

Henry Rosales-Parra (herosp@msn.com) is the Technology Manager for Integra Tecnología, a Colombia-based software-development company.concentrating on Mobile Enterprise Architecture. He has over 30 years IT experience and holds .