Modeling in an Agile ContextAlan Cameron Wills
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.
IntroductionModeling 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:
This article illustrates each of these uses. The tools that are discussed are available in Microsoft Visual Studio 2010 Ultimate. Exploring Existing ApplicationsMany—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 IncrementsAgile 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’ NeedsAgile 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:
Requirements Models and System TestsYou 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:
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:
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 PlanningIn 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 ModelsFrom 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:
Custom Modeling LanguagesIn 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:
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. ConclusionModels 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. AcknowledgmentsThanks to David Trowbridge, Jamie Cool, Steve Cook, Peter Provost, Stuart Kent, and Cameron Skinner. Further Reading
About the AuthorAlan 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 IlluminatiMichael 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:
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 DevelopmentHenry 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:
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 . |