Agile anti-patterns. Yes you agile projects can and will fail too

Over the years I have noticed a lot of agile anti-patterns during projects. Wrongly used agile approaches, dogmatic use of agile approaches, agile-in-name-only. Recently I have presented a talk at a number of agile and software development conferences that demonstrates patterns of agile misuse. These conferences include Agile Open Holland (Dieren), Camp Digital (Manchester), GIDS (Bangalore), ACCU (Oxford) and Jazoon (Zurich). Anyway, here’s the slide deck. Enjoy.

How Smart Use Cases Can Drive Web Development. Video for session at DevDays 2011 [in Dutch]

as the Channel 9 website says: using real-life code examples Sander will demonstrate how to model, generate and build smart use cases and introduce the positive impact smart use cases have on your layered software architecture.

Anyway, here’s the video for my DevDays 2011 session:

Please vote for my Microsoft Mix 2011 proposals!

From April 12-14 the next edition of Microsoft’s MIX Conference will take place in Las Vegas. I’ve sent in two proposals for the Open Call. Today heard that both proposals made it through the first cut, which means they’re open for public voting (you don’t have to be registered). It would be great if you would cast your vote for my proposals on how smart use case can drive web development, and on how frameworks can kill your projects.

300x250_Mix11_011011_US_b

Proposed talk 1: How smart use cases can drive ASP.NET web development

Use cases have been around for many years describing the requirements of software development projects. By developers, use cases are often seen as too abstract and too complex to develop code from. That is, until now.

During this interactive talk speaker Sander Hoogendoorn will demonstrate how to model, generate and build smart use cases. This great technique allows projects to model use cases at a much more pragmatic, and low-granular level, that can be implemented straightforward and directly into our applications, such as ASP.NET or Silverlight web application. The speaker will introduce both the positive impact smart use cases have on your layered software architecture, as well as the design patterns required to implement smart use cases. This talk comes with many real-life code examples.

Proposed talk 2: How frameworks can kill your projects

When it comes to .Net development, more and more frameworks enter the market. Both from Microsoft and from open source. think of ASP.NET MVC, Castle, WF, Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, WCF, nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF.

Once a project chooses to apply one or more frameworks, trouble begins. What if you require features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway your project? What if the author of your favorite open source framework suddenly stops developing? What if the framework contains bugs or omissions? And what if a new version of the framework is released that is implemented totally different? These and many more everyday problems will cause your project to come to a halt, or at least make you perform serious refactoring.

During this highly interactive talk Sander Hoogendoorn, chief architect of Capgemini?s agile Accelerated Delivery Platform, and member of Microsoft?s Partner Advisory Council .NET, demonstrates pragmatic architectures and patterns that will help your projects to stay away from framework issues, and how to keep code independent of framework choices. Sander will present models of layered architectures, and apply bridge patterns, managers-providers, dependency injection, descriptors, and layer super-types.

Of course, the speaker will illustrate these insightful patterns with lots of demo?s and (bad) code examples using blocks from Microsoft?s Enterprise Library, NHibernate, Log4Net, and the Entity Framework. Delegates benefit by learning how to improve the structure and quality of their software architecture and code, and how to avoid the pitfalls of applying frameworks to .Net software development.

November 25 & 26, 2010 – IT Works. Pragmatic modeling using UML

[Two day hands-on workshop at IT Works, Hotel Crowne Plaza, Antwerp. ]

On November 25 and 26 I will present the 32th edition of an intense two-day workshop on the pragmatic use of UML modeling techniques (and beyond) with lots of hands-on exercises.

IMAGE_073
Participants modeling activity diagrams with smart use cases

During this workshops we will go through the following subjects in depth:

  • A brief introduction of UML and its modeling techniques
  • A pragmatic YAGNI approach to modeling business processes and requirements.
  • Modeling hierarchical and chronological business processes.
  • Modeling traditional and smart use cases.
  • Modeling activity diagrams (for use cases).
  • Identifying test scenario’s for (smart) use cases using activity diagrams.
  • Modeling the user interface.
  • Modeling class diagrams.
  • Domain driven design.
  • Interaction modeling. Bringing together an applications structure and behavior, based on a pragmatic use case driven software architecture.
  • Modeling service oriented projects using smart use cases.
  • Modeling in agile projects.
  • A brief introduction to model driven software development.

November 12, 2010 – Microsoft TechEd Europe. How smart use cases can drive web development

[Session ARC205 at Microsoft TechEd Europe 2010 in Berlin]

Use cases have been around for many years describing the requirements of software development projects. From a developer’s point of view, use cases are often seen as too abstract and too complex to develop code from. Until now, that is.

IMAGE_004[5]

During this interactive talk, speaker Sander Hoogendoorn will demonstrate how to model, generate and build smart use cases.

image[8]_thumb[2]

This great technique allows you to model use cases at a much more pragmatic, low-granular level, enabling them to be implemented simply and directly into applications such as ASP.NET or Silverlight. Using many real-life code examples, the speaker will introduce both the positive impact that smart use cases have on your layered software architecture, as well as the design patterns required to implement them.

A recipe for enterprise agile. Mixing Scrum and Smart

To cut to the chase, those of you who have worked on enterprise or service oriented projects before already know this. These types of projects are characterized by a large number of organizational, functional and technically complicating factors. Enterprise software development projects are surrounded by a large number of complicating characteristics and challenges:

  • Many different stakeholders. Projects have many different parties in the organization that are involved. Often such project realize goals for different departments or divisions in the organization. As an example I once coached a project that served 22 different departments. Quite often these departments or division try to achieve overlapping or even contradicting goals.

IMAG0218[4]

  • Business processes. In general enterprise projects (re-)implement (parts of) business processes that are key to the organizations success, rather than building a straightforward web application.
  • Complex software architectures. Most likely, enterprise projects implement business processes in a complex IT landscape or architectures. Think of landscapes that host many different applications all tied together.

IMAGE_634[8]

  • Many external dependencies. Often, such complex IT landscapes contain components that are outside of the organization. Services that run outside the corporate firewall, with other parties. A well known issue to agile projects is that of availability. We need the new version of the service in this iteration, but the other party runs a waterfall project that will not deliver this year.
  • Changing requirements. In enterprise projects, requirements change continuously. Either by changing insights during the project, but more often due to changing legislation or regulations.
  • Many different types of deliverables. Traditionally these projects count many different types of deliverables. Think of service description, user interface, process models, non-functional requirements, workflow, project plans, test plans and many, many others.
  • Multiple roles. Large organizations count many different roles that are involved in projects. There are business analysts, enterprise architects, information analysts, testers, release managers, SAP developers, web developers, SAP functional consultants,

Thus these project often become a mission impossible, and fail in large numbers. Such projects are difficult to estimate, therefore hard to plan. For developers it’s tough to build the software, often with many new techniques and technologies, and even worse for testers, these projects are sheer Impossible to test well. This is where a structured agile approach should come to the rescue.

Being agile in enterprise projects

Independent of the approach that is applied, or the agile process that is followed, being successful in agile projects follows a number of key principles:

  • Multi-disciplinary teams. Instead of different roles such as analysts, designers, developer and testers working in consecutive stages in a project, all roles collaborate in implementation individual work items from heads to tales.
  • Short iterations. Project work in short time boxes, in most cases 2, 3 or 4 weeks. During such an iteration, a number of work items is planned, completed and evaluated – with different terminology in use with different agile processes.
  • A small standardized unit of work. Projects requires a small unit of work, to be able to deliver a number of them in a single iteration. Large work items such as traditional use cases therefore do not apply well.
  • Testing from day one. Testing is an important discipline during agile projects. Testers are involved from the very first iteration, when the first work items are realized. Note that testing in most projects goes way beyond the obvious unit testing – which is actually a developer technique.
  • Continuous measurement. Successful agile projects continuously measure their progress. Since they are always delivering individual work items, measurement in agile projects is easy.
  • Continuous (process) improvement. At the end of each iteration not only the realized work items are evaluated, but also the project approach itself is evaluated, leading to highly effective project approaches.

Scrum in a nutshell

When organizations first start with agile projects, Scrum is often the process of choice. At this point in time, Scrum is by far the most popular and best known agile approach. Scrum is a straightforward lightweight agile process that offers a collection of highly applicable principles and techniques for short iterative projects and is easy to understand. It also specifies a remarkable terminology with scrums, sprints and user stories.

image[3]

In a nutshell, Scrum is characterized as follows:

  • Sprints. Projects are divided into iterations, called sprints. In general these are 2 to 4 weeks.
  • Backlogs. Work items still to be done during a project reside in a so called project backlog. At the start of each sprint items from the backlog are placed in the sprint backlog. These are the worked items to be realized.
  • Sprint cycle. All iterations follow the same simple process, with an iteration kick-off, actual work and a retrospective workshop for evaluation.
  • User stories. The main unit of work is usually the user story, although this is not mandatory. This rather informal requirements technique is shared with the agile process extreme programming.
  • Planning. In general the project and sprint planning is visualized in task boards, which usually is put up on a wall using post-its. Progress is monitored by using burn down charts, a straightforward diagram that on a daily basis displays the number of points still to realize. A trend line in the burn down chart extrapolated from the points identifies the likely project end date. Again this technique is shared with a number of other agile processes, including Smart and extreme programming.
  • Delivery. Every iteration or sprint results in fully delivered products, software or otherwise.

Scrum has proven to be a successful approach in many (smaller scale) web projects. In larger, more complex, service or cloud oriented and enterprise projects, I think Scrum needs to be augmented to fit the project and its environment. Let me explain.

Beyond lightweight agile

When applying Scrum or other lightweight agile processes such as Crystal Clear or the set of lean principles (applied to software development that is) to more complex projects of all sorts, you might recognize a number of shortcomings:

  • Business goals. It is often unclear how the work items in such projects (in most cases user stories) link back to business goals, stakeholders and business processes to implement.
  • Analysis and design. Although many people in the so-called agile community will now think I’m promoting a waterfall approach, in most agile approaches there are hardly any analysis or design activities or deliverables defined.

    For instance, it is undefined how the backlog in a Scrum project is assembled. Let me assure you, in more complex projects some analysis and design is required, albeit not in big-upfront-design mode.

  • Architecture. The same argument goes for software architecture. Most agile approaches lack decent software architectural activities and deliverables. Architecture is often assumed as-is. If you’re implementing business processes that run through a systems landscape of over 40 collaborating systems, you will definitively need to design your architectures, but again this need not be in big-upfront-architecture mode.
  • Roles. Scrum and extreme programming describe a very limited set of roles that, although looking slick,  in most projects does not adhere to the standing organization. There’s often enterprise architects, information analysts, business analysts, middleware developers, application management, testers, release manager. How will a project work with all those roles? There’s a bit more to it than just saying they are allowed to participate in the daily scrum.
  • Testing. Apart from the obvious (developer) techniques such as unit testing, the role of testing more specifically – which is essential in larger agile projects – is not very well described in lightweight agile approaches.
  • User stories. Although very flexible, user stories are a highly unstructured unit of work, despite efforts in epics or story maps. Applying such an unstructured unit of work may result in low re-use, non-repeatable estimation, difficult to standardize development, testing and measurement beyond the individual projects. In a multi-project environment user stories will block progress and reuse (of for instance metrics and code).
  • Delivery cycle. Scrum does not specify the organization of delivery of the products to different environments such as test, acceptance and (pre)production (so called OTAP).

When executing large, more complex, service oriented or enterprise projects, I therefore strongly recommends to overcome these limitations by augmenting Scrum and the likes with additional techniques.

Smart accelerators

In my personal experience in enterprise projects I have had very good experiences with mixing the agile process Scrum with the best practices from another agile processes called Smart to overcome the drawbacks of the aforementioned approach.

Smart originated from the Netherlands in 1998 and was originally designed to implement best practices for DSDM, an iterative approach that was popular in those days. Later Smart grew out to a stand-alone agile approach that particularly combines well with other more basis agile approaches such as Scrum and extreme programming, but also aligns well with PRINCE2.

 image[7]

More specifically Smart puts accents on aspects in project that are only marginally highlighted in other agile approaches. As an example Smart adds the following accelerators to projects:

  • Preliminary iterations. Preliminary iteration types Propose and Scope is where work items are added to the backlog such as a modeling business processes, modeling smart use cases, creating an estimate, creating a cost-benefit analysis, writing a project plan (not that obvious it seems), first-cut software architecture set-up, development environment set-up, project kick-off, team education and first-cut user interface guidelines.
  • Smart use cases. Next to the more “non-functional” work items mentioned above, Smart introduces the well-known smart use cases requirements technique. Smart use cases not only model the needs of the user, but also identify workflow and reusable back-end services.

    This technique allows for identifying re-use, repeatable and reliable estimation, and very good traceability between requirements, architecture and code, great functional testing capabilities. An absolute must in enterprise projects.

ManageSite[2]

  • Estimates. Estimation of size and complexity of a project is estimated and measured in smart use case points, defined on a scale from 1 to 10. Smart use case points of course come from estimating the size or complexity of smart use cases, and is a highly pragmatic and repeatable technique..
  • Work item life cycle. Where Scrum’s work item life cycle contains to-do, working and done, in Smart, work items are delivered through a slightly more structured life cycle, that allows for all roles in enterprise projects to be maximally involved in a collaborative manner.

    Due to the life cycle, work items need not be broken down in tasks, a cumbersome and highly unstructured elements of Scum. In Smart work items simply move through the stages of the life cycle (in most cases in one or two days), the progress of which can be shown easily on a dashboard.

  • Designing. During the daily stand-up meeting, it is decided whether or not a design session is required. This time-boxed design session addresses the design or a single smart use case. Most project will organize this design session directly after the daily stand-up. On a typical time scale, if the stand-up runs from 10:00 to 10:15, the design session runs from 10:15-11:00.

    During such sessions all roles that need to deliver input to this particular use case participate. Of course also the developer and tester are present, so all roles create a homogeneous view of the smart use case at hand.

IMG_0247[4]

  • Smart testing. Working with user stories will normally not result in a very efficient test approach, as user stories do not add structure to the project. Smart describes a standardized approach on functional testing in agile projects of course based on smart use cases.
  • Stabilizing iteration. Usually the last iteration of a Smart project or the last one to an upcoming release is used to round off remaining work items, build issues, bugs, and remaining features. This iteration is merely used to stabilize the solution. In Smart this iteration type if referred to as Finalize.

Blending Scrum and Smart

Besides defining an obvious project life cycle, these best practices from Smart blend in really well with the more lightweight approach of Scrum and extreme programming. This leads to the following best practices:

  • Initial backlog. The initial backlog of the project is filled with the work items Smart recommends, rather than assuming a user story filled backlog. When prioritizing work items for the first sprint in a mixed Scrum and Smart project, it is very likely that these are picked.

    As a result, after one or two iterations, a project plan for the remainder of the project is produced, containing at least an estimate, based on the smart use cases that are also defined during these iterations (of course without any analysis or design, just the diagrams, the ovals and the actors).

  • Iteration kick-off. After the initial work-items are cleared from the backlog, the smart use cases become the primary work item type in the project. During sprint kick-off a number of smart use cases is picked to implement in the next sprint.
  • Dashboard. The traditional Scrum task board is replaced by Smart’s agile dashboard, containing columns for the stages in the work item life cycle – In Iteration, Designing, Working, Testing, Rework, Accepted. If appropriate additional columns can be added, e.g. when testing is split up in Developer Testing and Customer Testing.

IMAGE_041[7]

  • Points. The progress in the project is not measured in story points, but rather in smart use case points.
  • Scrum meeting. The focus of the daily scrum meeting shifts a bit as it is also used to answer the question: what still needs to be done on the smart use case(s) we’re currently working on to get them accepted?
  • Design. Host the design sessions as Smart recommends, preferably right after the daily scrum meeting. 
  • Testing. As the work item life cycle clearly stipulates, functional testing, often done manual is all in a days work. The role of the testers here becomes imminent in the project.
  • Finalize. Projects have to decide when to apply a Finalize iteration to stabilize the solution and round up loose ends. Depending on the type of project, these iteration can be the very last sprint, but also can be very well aligned with the organizations release calendar.

This approach of mixing best practices, techniques and tools from Scrum, Smart over the past 12 years has proven to be very successful in a variety of projects and project types, including larger Java and .NET projects. service oriented projects, business intelligence projects, and even packaged implementations.

Moreover, when augmented with more technical best practices from extreme programming, such as refactoring, continuous integration, pair programming, and test driven development (smart use cases are a very good unit for unit testing code) projects are aligned to deliver on-time, on-budget, and with just-enough documentation and fitting (reusable) features. As former US president Bush used to say: failure is not an option.

Being Smart in enterprise agile

As agile is becoming more and more mainstream, organization are starting to do enterprise software development project using well-known but fairly basic lightweight agile processes.

IMAGE_089 

In many projects this has lead to surprisingly bad result, baffling the agile Certified Pokémon Trainers who are coaching these projects. The presentation below shows a number of accelerators or technique that projects can apply to tackle the challenges of enterprise agile projects.

Would be happy to hear your comments!

Sander’s talk at TechEd US 2010. How frameworks can kill your projects and patterns to prevent getting killed

Last week, the Microsoft TechEd North America 2010 took place in the great city of New Orleans. I was lucky to be invited to do a talk on how frameworks can kill your projects.

When it comes to Microsoft .NET-connected development, more and more frameworks enter the market. Both from Microsoft and from open source. Think of ASP.NET MVC, Castle, Windows Workflow Foundation (WF), Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, Windows Communication Foundation (WCF), nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF.

Trouble begins

Once a project chooses to apply one or more frameworks, trouble begins. What if you require features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway through your project? What if the author of your favorite open source framework suddenly stops developing? What if the framework contains bugs or omissions? And, what if a new version of the framework is released that is implemented differently? These and many more everyday problems will cause your project to come to a halt, or at least make you perform serious refactoring.

Get Microsoft Silverlight  

Demos and (bad) code

During this highly interactive talk, Sander Hoogendoorn, chief architect of Capgemini’s agile Accelerated Delivery Platform, and member of Microsoft’s Partner Advisory Council .NET, demonstrates pragmatic architectures and patterns that will help your projects to stay away from framework issues, and how to keep code independent of framework choices. Sander presents models of layered architectures, and applying bridge patterns, managers-providers, dependency injection, descriptors, and layer super-types.

Of course, Sander illustrates these insightful patterns with lots of demos and (bad) code examples using blocks from Microsoft’s Enterprise Library, NHibernate, Log4Net, and the Entity Framework. Learn how to improve the structure and quality of your software architecture and code, and how to avoid the pitfalls of applying frameworks to .NET software development.

PowerPoint Architecture

It’s a mildly sunny April morning in 2002 when I park my car outside of a huge government agency office in a small suburban city near Utrecht. I am invited for a brainstorm session with the agency’s enterprise architects. Although I do not consider myself an enterprise architect, and explained that upfront, they were eager to discuss their architecture with me. Ok.

After registering at the reception, I enter the meeting room. Now this might be specific for the Netherlands, but the enterprise architects are sitting at an oval table, all equal in our consensus world. “So what is it you’re doing?” I ask, while looking at the architect who looks more equal than the others. Happy to be addressed the architect, bearded and all, stand up and walks to the whiteboard, picks up a marker and starts telling their story.

Rectangles and arrows

While talking our bearded architect starts drawing the different application and systems in their system landscape. Each represented by a rectangle with a three to five letter acronym on the white board. The big challenge for this government agency, so I understand, is to from a tightly integrated system landscape to a service oriented landscape with an enterprise service bus.

image 

Next my bearded friend starts to discuss the connections between the different systems and the enterprise service bus. Here come the arrows! “So we connect each system to the bus, and we will have upgraded our landscape for the future,” the architect smilingly concludes. I nod my head willingly. “Looks good,” I start complimenting the architect. “But,” I continue, “how are these arrows implemented?” “Well, that’s easy,” says the architect. Without saying a word he picks up the marker again and slowly adds the acronym SOAP to one of the arrows on the white board. “That’s all.”

SOAP

Now, from an enterprise architect’s point of view that might be all, but from a developer perspective drama begins here. I roughly estimate that each of these fancy little SOAP arrows likely represents about 4 to 8 weeks of work – note: it is still 2002. And there are quiet a few of these arrows on the whiteboard; and the view is likely not the complete picture.

image

Concluding: what might seem insignificant and trivial from an architectural perspective, might be complicated and elaborate from a developer’s and tester’s point of view. Or as Scott Ambler so eloquently puts it: everything works on a PowerPoint slide. And sorry dear architects, it just doesn’t, no matter how brightly colored and great looking your PowerPoint presentation are.

Wouldn’t it be good if enterprise architects actually participate in projects to see in real life what these simple drawn decisions. Actually, it is good. For some years now, in the agile projects I am coaching enterprise architects, business and information analysts take part during the actual iterations. Instead of upfront, untested architectural demands or long review periods afterwards, they actually participate in the design workshops of the project. And you know what? They love it. It’s simply great to actually see directly what comes out of what you so cleverly think of. And even better: you, as an architect are totally rid of these long and cumbersome review period, and you directly get to influence the way the software is built. Please do.

The penultimate goal

Can you do even better? Well, there’s a penultimate goal. In September 2003 I did a talk at a large software development conference in Denmark. During the speaker’s dinner I found myself at a table with some great names in this field – think of Bjarne Stroustrup, Jos Warmer, Kevlin Henney – and even bigger glasses of cool Danish beer. Nerds as we were, by the end of the evening we concluded that this particular conference should have a panel discussion with 42 panel members, and we would name it The Panel at the End of the Universe. Great thinking!

image

And about an hour and many glasses of beer later, we agreed upon an even bigger contribution to the field of software development. We thought that the penultimate solution to developing software is to be able to generate software directly from the rectangles and arrows in the architect’s PowerPoint presentations. That would sure boost productivity!  Then we could actually say that everything does work on our PowerPoint slides.

Extension methods (with DevDays 2010 slides)

This post was originally published in .NET Magazine. I re-posted it because of the talk I did at Microsoft’s DevDays 2010 in Den Haag recently.  The slides for this talk can be downloaded here.

As you’re probably have been made aware of in abundance, in .Net 3.5 Microsoft introduced a little language feature called LINQ. Although LINQ has been demonstrated at all major and minor conferences, the way LINQ executes queries on already existing types remained slightly less apparent. To this means LINQ introduces a number of new query operators, using yet another new language  feature called an extension method.

Download slides from my DevDays 2010 talk on extension methods here.

 

Basically, there are two sets of LINQ query operators. One set that operates on objects of type IEnumerable and another set that operates on objects of type IQueryable. To implement the methods in these sets, the .NET architects chose to add something called extension methods, and write the required methods as extension methods to the Enumerable and Queryable classes, instead of directly extending these classes – which would seriously pollute the .NET framework.

Defining a simple extension method

Apart from the apparent use of these extension methods in the query operators of LINQ, there is slightly more to it. At first sight, extension methods appear to allow you to extend any class in any namespace with additional functionality. Let’s have a closer look at them by using an example.

One of things I always disliked about working with the DataSet class is that to obtain the value from a column in a row in a table, I’d have to write code that looks at lot like this:

public void DoTraditionalTest()
{
    DataSet ds = new DataSet();
 
    object o = ds.Tables[2].Rows[4]["Name"];
}

This code is both tedious and poor code however, as it doesn’t do any check on whether the table and row are actually available. As you’ve probably all have written code like this before, you would probably have appreciated a method like Get() on the DataSet class, like I’m using in the following code example, where Get() performs all necessary checks and formatting.

public void DoTest()
{
    DataSet ds = new DataSet();
 
    object o = ds.Get(0, 0, "Name");
}

The issue here is that you cannot extend the .NET framework class DataSet to encapsulate this functionality. This is where extension methods come in neatly. With .NET 3.5 I can now write a method such as the following.

namespace Extensions
{
    public static class DataSetExtensions
    {
        public static object Get(this DataSet ds, int table, int row, string column)
        {
            if (table >=  0 && table <= ds.Tables.Count)
            {
                if (row >= 0 && row <= ds.Tables[table].Rows.Count)
                {
                    return ds.Tables[table].Rows[row][column];
                }
            }
 
            return null;
        }
    }
}

If you’ve never seen an extension method before, the first parameter will appear strange to you. The this keyword is added to it to show that this Get() method works on the DataSet class. Although this method is defined as a static method on a class called DataSetExtensions, it is recognized as an instance method on the DataSet class.

image

Intellisense even recognized my method, and the code comments I’ve added. The only difference between an instance method and an extension method from an intellisense point of view, is that you’ll still be able to notice the this parameter in the signature of your extension methods. Of course, the same goes for .NET framework defined extension methods, like the LINQ Where() method, which also displays the this parameter.

image

Extension methods and the Open Closed Principle

Doesn’t that look cool? I think so. When I first read about extension methods I immediately thought of a whole bunch of functionality that I could add not only to our own frameworks, but also to open source and  even the .NET framework itself. But before bloating out lots of code, let me give you some caution.

My biggest worry was whether extension methods would allow me to break existing framework code. There’s a well known principle that needs to be examined here, which is called the Open Closed Principle (OCP). In short, this principle states that classes should be open for extension, but closed for moderation. In general I think this is a principle well worth living by. So, the big question is: do extension methods allow me to change the behavior of existing classes? What happens if I write an extension method, such as the one below?

namespace Extensions
{
    public static class ObjectExtensions
    {
        /// <summary>
        /// Testing whether I can override the ToString() method.
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>My own string.</returns>
        public static string ToString(this object o)
        {
            return "Sander is always right.";
        }
    }
}

The question is, by writing this simple extension method, did I just override the ToString() method for all classes in my applications? Surely, such extension methods would kill a lot of projects really fast. Of course the .NET architects do not allow you to do so. There’s thing or two you should know about how extension methods work, and about how they are compiled.

Compiling extension methods

First, they’re defined within the context of a namespace, Extensions in the example above. To use an extension method on a class in your code, you will need to add a reference to the namespace that contains the extension methods. Without this reference, the method don’t even show up.

Second, and even more important, extension methods are in fact just static methods on a static class, as can be seen in intermediate language (IL). Extension methods only appear in your code editor as instance methods on the target class. The fact that they’re defined as static methods outside of your target class means that in an extension method you can only get to the public properties the target class exposes, but you will not be able to reach the protected and private fields of this class, nor will you be able to define new properties or fields.

Even more important, it is interesting to notice what the compiler does with your extension methods, especially in the case that you would define a method with the same signature as the method in the target class, like with the ToString() method above.

The compiler follows a straightforward rule: extension method always have a lower priority that real instance methods. As a consequence, when the compiler tries to resolve a method invocation it first looks in the target class for methods with matching signature, and consequently in its ancestors, and bind to this method if located. Only if no instance method is found, will it start to look for extension methods with the same signature. Following this convention the ToString() method I’ve defined above will never be called, as the object class defines a method with a matching signature.

Even when I try to create a (very stupid) extension method like the one below, targeting the Equals(string s) method just for matching with a string, the compiler will still bind to the Equals(object o) method from the object class, even if it has a wider scope – it compares with an object, not a string.

public static bool Equals(this object o, string match)
{
    return match.Contains("Sander");
}

This compiler directive satisfies my concerns. Using extension methods, you will not be able to alter any existing functionality. You can not override existing methods, nor get a hold of private or protected fields. In fact, the extension method totally live outside of the target class. So, you’re quite safe.

No worries then?

Well, there’s something else that concerns me about extension methods. The most demo’s I see on extension methods worry me. There seems to be no end to people extending the String class. I’ve seen demo’s that check whether a string is a valid email address, a valid URL, and even extensions that speak out a string using a synthesizer – although I expect good craftsmanship, not really something I long for in my applications.

It’s just that stuff like this should not be extensions to the string class. Unless at least 50% of all strings you use in your code are in fact email address, I would consider a different pattern here, such as defining value objects of type Email, Zip or whatsoever. In general, my concern with extension methods is that it’s such a neat little technology, that it will invite people to use it for all the wrong reasons – just because it’s fun to define an extension method for instance.

Before you know it, the developers in your project will have defined loads of extension methods, to all kinds of framework classes. You should be well aware of the possibilities this offers to break your application architecture and create lots of undesired dependencies. Just take a quick look at the following example.

using System.Workflow.Activities;
 
namespace Extensions
{
    public static class CodeAcitivityExtensions
    {
        public static bool Kill(this CodeActivity activity)
        {
            activity.Dispose();
        }
    }
}

Here, I’ve added an extension method to the CodeActivity class, which resides in the namespace System.Workflow.Activities. Now my Extensions namespace has a dependency on this namespace, and moreover, also on the underlying System.Workflow.ComponentModel namespace.

However, my previous code example where I extended the  DataSet class also resides in my beautiful Extensions namespace. So from this day forward, every time I use my Get() extension method for DataSet, I’m indirectly also connected to the workflow namespaces. Just as an example.

Furthermore, when you define an extension method to extend a type delivered by a framework, you also run the risk that your extension method will cause your code to break if the implementation of that type changes, or if your project migrates to a newer version of that particular framework, of .

Extending framework base classes

On the good side, you will more likely use extension methods that other developers have written, than define your own. Here, extension methods are a powerful features, as applying extension methods does not require any additional knowledge. Most extension methods will be written by frameworks developers, who now will feel enabled to solve anomalies. Or even more likely by developers who feel the need to extend base classes from existing frameworks, both from Microsoft and open source, such as in the following example, that extends the open source frameworks CSLA.

One of the most reused base classes in the CSLA framework is called BusinessBase. It serves as layer supertype for all domain objects in applications built with the framework. The BusinessBase class has the ability to validate its business rules. To this means it stores a broken rules collection that contains references to business rules that are violated during a validation of your domain object.

In some cases, for instance when displaying violated business rules on screen, it can be handy to know which business rules were broken per property. The BusinessBase class however, does not have this ability.

public static IEnumerable<BrokenRule> GetBrokenRules(this BusinessBase bb, string property)
{
    var queryableList = new List<BrokenRule>(bb.BrokenRulesCollection);
    IEnumerable<BrokenRule> result;
    if (!string.IsNullOrEmpty(property))
    {
        result = from brokenRule in queryableList
                 where brokenRule.Property.Equals(property)
                 select brokenRule;
    }
    else
    {
        result = queryableList;
    }
    return result;
}

The code example here displays an extension method for BusinessBase that loops through the total collection of broken rules using a LINQ query that filters the broken rules for the selected property (using the property’s name). This method is very useful and powerful example of how developers can tweak the functionality of framework classes. It should come as no surprise that many more such extension methods will become available from the community soon for popular frameworks such as Microsoft’s Enterprise Library, nHibernate, ADF, CSLA and of course for the .NET framework itself.

Handle with care

Extension methods are a language feature that does not really stand out in the crowd, but can be very useful, especially to avoid repetitive work that should have been a feature of frameworks you apply to your projects. However, when developing extension methods you will need to be very aware of the side effects described above. I therefore recommend to implement extension methods sparingly. Under normal circumstances, you will still extend existing types by inheriting from them, even though this requires your developers to use your new class by convention instead of an extended base class. To leave you with a proper quote: “Creativity is a natural extension of our enthusiasm.”

Alzheimer Architecture

Let’s suppose for a moment that it’ is 1986. And let’s suppose you are starting a new company. A company that sells products or services to customers, as most companies do. Let’s say you selling (surf) board wear. You start selling your first t-shirts and you decide that you need to automate stuff. So you create a list of your customers in Excel, and type orders and bills in Word.

Someone’s father-in-law

After a while business is picking up, more orders are coming in, more boards, t-shirts and shorts are sold, and customers are even returning to your shop. This is where things are starting to get a bit nasty. You are starting to see the need for real automation. So you start asking your friends, until eventually you find someone who has some knowledge of Microsoft Access, mainly because he is using it to print address labels for his christmas cards.

A short while later your new developer, in most cases some friend’s father-in-law, a former accountant, has built you a simple application to maintain customers, orders and delivery statusses. It’s now 1990.

At a regular basis your thinking of new stuff to sell, and worse, of new ways of selling stuff, perhaps even through the internet. This poses new features to your Visual Basic for Applications written back office application. Hence the application grows and grows. Because software architecture is light in Microsoft Access, and software architecture knowledge is not apparently present in your developer’s skills, the code grows in all directions.

Three-table-and-a-screen

Now we’re back in 2010. Because business is still going strong, your 1986 back office application is still there, although it has grown from a simple three-table-and-a-screen maintenance thingy to a code base of over a million lines of code that interacts with external parties for billing, the cash registers in your shops, and also does your enterprise resource planning, including stock and shipments.

image 
Three-tables-and-a-screen

And although your friend’s father-in-law still oversees all of the code, implementing the new features you need for your evolved business is getting harder and harder. “Hey, we need to be able to deliver goods in Belgium and Germany too,” you claim. The developer sighs. “Phoe, that is a major change to the system. It’ll take me about three weeks.” With every bug, change or new feature you hope to introduce, the productivity of your developer lowers. Moreover it is due to these changes and new features that always need to be introduced fast, that the software architecture of the system has never been upgraded to facilitate some layering, introduction of patterns, or even migrated to a more serious development platform. There’s just never the time to do it.

Turning 75

To cut a long story short, these days that is not even your biggest issue. The biggest problem is that the only person capable of maintaining the code is still your friend’s father-in-law, who grey haired, these days, is seriously thinking of retiring. Or even worse.

image
Alzheimer Architecture 

Recently I visited a customer who needs to rebuild her current back office application – and yes, it is written in Visual Basic for Applications. And she needed to rebuild the application really fast. Why? Well, the single developer of the system who had uphold the code for almost two decades is not only thinking of retirement, but actually did retire ten years ago. He had recently turned 75, and was now moving into a home for the elderly.

No cure

Unfortunately, there’s no easy way out of this rat hole:

  • Automated migration will not do the trick, as there’s so many lumps and bumps in the software, that automated tooling will never identify all the finesses in the code.
  • Introducing a packaged applications, such as Micrsoft CRM, Salesforce.com, or even SAP or Oracle, is not only expensive, but how do you capture all exceptions and loop holes you’ve introduced to satisfy your customers in such a package?
  • Offshore development is hard too because your whole company, which likely has grown from a happy few to over a hundred employees, is depending on the system. How do your guarantee quality? And who do your trust?
  • Rebuild the system yourself in .NET or Java is also not a very plausible option. There’s no expertise in the company, and moreover, you will need the domain knowledge of your employees who are always very busy with their regular work.

This is when you realize your suffering from the Alzheimer Architecture anti-pattern. It’s a progressive anti-pattern. With each business discission you take, the problems grow, and there’s just never time nor budget to solve it properly. It is as it goes with Alzheimer’s disease. Unfortunately there is no cure.

Service georienteerde projecten vormgeven met smart use cases [In Dutch]

This post was originally written to be published as a chapter in an upcoming book on IT architecture. The book will be presented at the Landelijk Architectuur Congres 2009 in Nieuwegein, The Netherlands. This post will likely also be published in two parts in Software Release Magazine.

Ondanks dat ik inmiddels al zo’n twintig jaar in dit vakgebied rondloop, blijven software development projecten uitdaginen opleveren. Zo werkte ik eerder dit jaar coach aan een agile project waarmee een grote logistieke onderneming nieuwe producten voor hun klanten ontsloot.

Alhoewel ik vooral als coach was ingezet op het begeleiden van het proces, was het project technologisch een hele kluif. Een Java portal als front end, orchestratie van processen in SAP middleware, back office systemen in PeopleSoft, SAP en .NET die moesten worden “verserviced”, en niet te vergeten een aantal interfaces naar externe systemen, waar we niet of nauwelijks invloed op konden uitoefenen. Al met al een typisch voorbeeld van een service georienteerd project. Dit type projecten kenmerkt zich door hun hoge complexiteit, en zijn daarom slecht in te schatten en te plannen. Alhoewel niet de oplossing voor alle uitdagingen, bestaat er een techniek die smart use cases wordt genoemd, die concreet en pragmatisch bijdraagt aan het beter inschatten, plannen, maar ook realiseren en testen van servicegeorienteerde projecten.

Service georienteerde projecten zijn complex

Iedereen die in dergelijke projecten heeft gewerkt, weet het inmiddels wel: service georienteerde architecturen maken het uitvoeren van dit soort projecten er niet makkelijker op. Dit soort projecten kenmerken zich een groot aantal organisatorisch, functioneel en technisch complicerende factoren:

  • Diverse stakeholders. Servicegeorienteerde projecten automatiseren in het algemeen bedrijfsprocessen, die meestal meerdere organisatorische eenheden en verschillende systemen doorsnijden. Dientengevolge zijn er vaak diverse stakeholders betrokken bij het project.

IMAG0071

Een servicegeorienteerd project kent vele stakeholders

  • Flexibele front end technologien. Voor het realiseren of uitbreiden van de front end(s) wordt vaak gebruik gemaakt van state-of-the-art, of zelfs bleeding edge technologie, waarover niet altijd evenveel kennis beschikbaar is in de organisatie.
  • Heterogene back end technologien. De diverse systemen die ontsloten dienen worden – verserviced – zijn gerealiseerd in allerhande technologien, al dan niet verouderd.
  • Externe interfaces. Niet zelden wordt ook gebruik gemaakt van systemen die extern zijn aan de organisatie. Op deze systemen kan het project meestal weinig invloed uitoefenen, hooguit zijn de interfaces bekend. Helaas zijn dit soort interfaces zelden stabiel, en aan wijzigingen onderhevig.
  • Diverse rollen. Opvallend aan service georienteerde projecten is dat er een breed scala aan rollen betrokken is. Zo zorgt de diversiteit aan technologie al voor een breed palet aan developers – zo is een SAP CRM consultant geen SAP XI developer, en een .NET developer niet per se ook een software architect. Maar ook andere traditionele en minder traditionele rollen al informatie-analisten, ontwerpes, user inferface designers, enterprise architecten, business consultants en last but not least project managers, vinden hun weg in dit type projecten.

Service georienteerde projecten zijn lastig te plannen

Een recent voorbeeld is een project voor een verzekeraar voor het realiseren van een nieuw hypotheekoffertesysteem. Belangrijkste streven bij dit project was het realiseren van straight-through processing (het zonder humane tussenkomst doorvoeren van hypotheekoffertes naar de back office) en het flexibel kunnen toevoegen van nieuwe hypotheekproducten.

Naast de haast traditionele handicaps als schuivende requirements, bleek gedurende het project dat de interfaces van externe systemen niet aansloten op de gegevens die nodig waren om de benodigde processen uit te voeren. Daarnaast bleek ook de gebruikersvriendelijkheid van de (gegenereerde) webpagina’s tot hoofdbrekens te leiden. Het project levert nu hopelijk ruim een jaar na dato op, en heeft ruim vier keer zoveel gekost als oorspronkelijk begroot.

Maar waarschijnlijk vertel ik u als lezer hiermee nog niets nieuws. Lastig is wel dat deze complexiteit voor uw project een aantal ondermijnende gevolgen kan hebben. Om u een indruk te geven laat ik er hier toch maar een paar de revue passeren:

  • Externe afhankelijkheden. Service georienteerde projecten zijn vrijwel zonder uitzondering afhankelijk van derden, ofwel partijen binnen de eigen organisatie die andere planningen er op nahouden, ofwel partijen buiten de eigen organisatie, die lastig beinvloedbaar zijn.
  • Moeilijk in te schatten. Wie al eens in een offertetraject voor een dergelijk project heeft geparticipeerd; het maken van een goede schatting is cruciaal maar extreem lastig.
  • Moeilijk te plannen. Lastige schattingen, diverse stakeholders, externe afhankelijkheden, en talrijke projectrollen maken het er niet makkelijker op voor de beoogd project manager om een goed planning voor het project af te leveren.
    Een ding is zeker: een traditionele lineaire aanpak, waarin flexibiliteit tot een minimum wordt beperkt, is uit den boze. Een service georienteerd project kent vele wendingen – steeds meer overigens naarmate het project langer duurt.

Het zal u niet verbazen dat met deze consequenties service georienteede projecten te vaak niet op tijd en op budget worden opgeleverd, of dat gaandeweg het project wordt besloten slechts een deel van de vereiste functionaliteit op te leveren. Tenslotte worden de beoogde uitgangspunten voor het project vaak niet gehaald. Denk daarbij aan het in service ontsluiten van legacy back end systemen, het realiseren  van hergebruik ten einde toekomstige projecten sneller te kunnen uitvoeren, het opbouwen van een repository van services or het snel en flexibel kunnen toevoegen van nieuwe producten en features.

Hoe complex is het project eigenlijk?

Zoals gezegd zijn service georienteerde projecten meestal lastig te schatten en derhalve nog lastiger te plannen. Een belangrijk vraag die bij aanvang van dit soort projecten dan ook dient te worden gesteld om een goede kosten-baten-analyse te kunnen maken is: hoe groot en complex is ons project nu eigenlijk?

Een belangrijk struikelblok bij het beantwoorden van deze op het oog eenvoudige vraag is dat er allerlei verschillende typen deliverables zijn te onderkennen in een service georienteerd project. Denk hierbij bijvoorbeeld maar aan webpagina’s, schermen, services, orchestratie, domeinobjecten, transacties. Dit maakt het “tellen” van de totale complexiteit van een project lastig. En zelfs wanneer al deze verschillend typen deliverables zouden kunnen worden geteld, dan nog ontbreken er de nodige ervaringscijfers, die de uiteindelijke complexiteit per type deliverable in uren kunnen helpen vertalen.

IMG_0242

Smart use cases modelleren in een servicegeorienteerd project

Het zou een belangrijk stap voorwaarts voor servicegeorienteerde projecten kunnen zijn wanneer alle (functionele) deliverables op een en dezelfde schaal konden worden uitgedrukt, waarbij de complexiteit van zowel de webpagina’s, schermen, orchestratie als services op eenzelfde manier wordt uitgedrukt, middels een enkele eenheid van schatten, en misschien zelfs wel een enkele eenheid van werk. Immers, zo kunnen makkelijker ervaringscijfers worden verzameld, die weer kunnen worden toegepast om volgende projecten binnen hetzelfde programma beter in te plannen. Deze eenheid van werk dient zich aan door smart use cases te introduceren in service georienteerde projceten.

Use cases

Laat ik bij het begin beginnen. Wat zijn eigenlijk use cases? Meestal wordt een use case aangemerkt als een beschrijving van het gedrag dat software vertoont als reactie op een verzoek dat stamt van buiten de software. Vrij vertaald beschrijft een use case wie met de software wat kan doen. Een use case realiseert een bepaald doel voor uitvoerder van de use case. In jargon wordt deze uitvoerder wel de actor genoemd. Zo’n actor hoeft overigens niet perse menselijk te zijn, maar kan bijvoorbeeld ook andere software zijn of zelfs een batchverwerking.

Het uitvoeren van de use case vindt plaats als een opeenvolging van een aantal stappen. Deze stappen vormen tesamen een of meerdere scenario’s die uitmonden of in het realiseren van het doel, of, wanneer er iets mis gaat, in een uitzonderingssituatie. Deze eindresultaten worden wel de postcondities van de use cases genoemd. Use cases worden veelal beschreven in documenten, al dan niet geformateerd in een voorgeschreven sjabloon.

ManageSite

Voorbeeld van een use case diagram

Daarnaast bestaat er een aardige, relatief informele en veel toegepast modelleertechniek, waarin actor als poppetjes worden gerepresenteerd, en use cases als ovaaltjes. Deze modelleertechniek, die het use case diagram wordt genoemd, wordt ondersteund door een breed scala aan geautomatiseerde gereedschappen.

Traditionele use cases

Traditioneel worden reguliere use cases gebruikt voor het beschrijven van de functionele requirements van een regulier project, uitgaande van het doel dat de gebruiker (of actor) wil bereiken door de use case uit te voeren. Traditioneel worden use cases beschreven in een document, dat naast het doel, het resultaat ook alle mogelijke scenario’s beschrijft aan de hand waarvan de use case kan worden doorlopen.

Een interessant voorbeeld van een dergelijk use case kwam ik tegen in een service georienteerde project bij een interrnationale bank, waar een use case Wijzigen Adres een document van vijfenzestig pagina’s besloeg, waarin twaalf schermen voorkwamen, tientallen scenario’s en waarin diverse services werden aangeroepen. Een ander gelijksoortig voorbeeld is een use case Uitvoeren Kwartaalfacturering van een pensioenfonds, waarbij circa 1.3 miljoen factuurregels werden berekend.

Alhoewel dergelijke use cases  in service georienteerde meestal de te realiseren bedrijfsprocessen beschrijven, zijn ze niet bijzonder geschikt als eenheid van werk en van schatten in dit type projecten. Traditionele use cases verschillen te veel in omvang en complexiteit, om ze met een gerust hart op een lineare schaal uit te drukken. Ter ondersteuning: het realiseren van de use case Uitvoeren Kwartaalfacturering vergde ruim anderhalf jaar, terwijl het in hetzelfde project slechts enkele dagen kostte de use case Inloggen Gebruiker in te voeren.

Daarbij komt nog het bezwaar dat deze wijze van benaderen van use cases niet bijdraagt aan het identificeren en realiseren van de gewenste services, en dat hergebruik slechts sporadisch en incidenteel tot stand komt.

Smart use cases

Toch hebben we in de afgelopen jaren ervaren dat use cases een heel nuttig vehikel kunnen zijn in servicegeorienteerde projecten. En niet alleen om projecten in te kunnen schatten, maar ook als eenheid van werk, en zelfs voor het identificeren en hergebruiken van services. Om deze nobele doelstellingen te bereiken maken we intensief gebruik van wat we in de loop der jaren smart use cases zijn gaan noemen – genoemd naar de agile methodiek Smart en goed beschreven in mijn boek Pragmatisch modelleren met UML. Een korte introductie.

Alistair Cockburn, autoriteit op het gebied van use cases, beschrijft in zijn boek Writing effective use cases een model waarin use cases in vijf verschillende niveau’s van granulariteit – zeg maar grootte en complexiteit – worden uitgedrukt.

image

Deze niveau’s zijn:

  • Cloud. Use cases op dit hoogste niveau representeren veelal groepen van samenhorende bedrijfsprocessen, zoals Verkopen Producten.
  • Kite. Op dit tweede niveau worden in de regel individuele bedrijfsprocessen geposteerd, vaak workflow georienteerd.
  • Sea. Dit is het niveau waar het om draait, en waar bijvoorbeeld ook Wijzigen Adres toe behoort. De kernvraag op dit niveau zou kunnen zijn: hangt de performance van mijn organisatie af van hoeveel van deze kan ik per dag uitvoeren? Als richtlijn: deze use cases komen nagenoeg overeen met wat ook wel als elementaire bedrijfsprocessen wordt geduid.
  • Fish. Use cases op fish niveau worden gebruikt om op zichzelfstaande, maar aan sea niveau ondersteunende functionaliteit te modelleren. Denk bijvoorbeeld aan Ophalen Abonnement of Selecteren Product.
  • Clam. Soms modelleren projecten te ver door, en worden de use cases te klein. Hier spreekt men over clam niveau.

Ondanks de beknoptheid van deze introductie, moge het duidelijk zijn dat cloud en kite niveau in servicegeorienteerde project met name terug te vinden zijn in de te automatiseren bedrijfsprocessen, de visie van het projec en wellicht de bedrijfsarchitectuur van de organisatie.

De use cases op het sea en fish niveau worden samen smart use cases genoemd. Deze twee niveau’s vormen zo een goede basis van gelijke granulariteit zowel voor het uitdrukken van functionaliteit die direct zichtbaar is voor de gebruiker, zoals Selecteren Product, maar ook voor het identificeren van services, en het aanleggen van een repository van deze services, zoals Ophalen Abonnement.

Smart use cases modelleren

Veel meer dan in traditionele use cases het geval is, gebruiken we voor het vormgeven van smart use cases de bijbehorende modelleertechniek.

Uitgaande van de lijst te realiseren bedrijfsprocessen op kite niveau, modelleren we een use case diagram per elementair bedrijfsproces, op sea niveau derhalve. Ieder use case diagram bevat:

  • Sea niveau use case. Een enkele use case die het elementair bedrijfsprocess representeert, weergegeven als een ovaal.
  • Actoren. Een of meerdere partijen die gebruik maken van deze use case, om daar hun doel mee te bereiken, weergegeven als poppetjes.
  • Fish niveau use cases. Nul, een of meerdere use cases die ondersteunend zijn aan de sea niveau use case, eveneens weergegeven als ovalen.

Onderstaande figuur bevat een goed voorbeeld van een dergelijke use case diagram .

Task

In dit use case diagram zijn de use cases Apply for Membership en Activate Membership sea nieuws use cases, de overige use cases zoals Send Confirmation en Validate Creditcard zijn fish niveau.

Om tot dit diagram te komen distilleren we normaliter de fish niveau use cases uit de sea niveau use case, door onszelf steeds opnieuw te vragen: wat is de volgende stap die we nemen bij het uitvoeren van deze use case? In sommige gevallen is het handig om deze stappen als individuele use cases op te nemen in het diagram, in andere gevallen weer niet. We hanteren hiervoor een set aan richtlijnen, zoals aan het identificeren van hergebruik – komen we deze use case mogelijk vaker tegen? Of denk het afhandelen van alle interactie rond een formulier of scherm, of het importeren en exporteren van bestanden.

Standaard typen smart use cases

Deze hierboven beschreven aanpak is inmiddels – met veel succes – toegepast in een diverse typen projecten, zoals reguliere webprojecten in .NET of Java, het implementeren van portals, business intelligence en zelfs pakketimplementaties.

Bij het uitvoeren van al deze projecten is vooral opgevallen dat steeds opnieuw dezelfde soorten smart use cases de revue passeren. Denk hierbij aan het selecteren, zoeken, of onderhouden van gegevens, het exporteren van een bestand, of het aggregeren van gegevens in een business intelligence situatie.

Deze standaardtypen use cases (in de wandelgangen stereotypen genoemd) helpen projecten enorm om de analyse van de requirements te versoepelen en standardiseren. Het jargon van smart use cases wordt tijdens workshops al snel overgenomen door opdrachtgever en gebruikers. “Ik stel voor dat hier hier een master-detail over klanten en orders gebruiken, met een search op producten”.

Belangrijk bijkomende voordelen van het toepassen van deze (of eigen) stereotypen is dat ook het schatten van de omvang van het project vergemakkelijkt, en dat ook de realisatie, inclusief testen, van dit soort standaard use cases eenvoudiger is. Immers, er is al eens eerder met hetzelfde bijltje gehakt. Een onderhouds-use case voor klanten verschilt niet wezenblijk van een onderhouds-use case voor producten.

Smart use cases modelleren in servicegeorienteerde projecten

Ook in servicegeorienteerde projecten hanteren we sinds enkele jaren smart use cases. Daarbij brengen we graag een tweedeling aan, we modelleren een front end use case diagram, en een service use case diagram.

Allereerst modelleren we een smart use case diagram vanaf de sea level use case die de interactie met de gebruikers en het elementaire bedrijfsproces vertegenwoordigt, zoals Aanvragen Subsidie. Daarbij identificeren we de bijbehorende fish level use cases, maar alleen  tot aan het aanroepen van de services of de orchestratie.

Smart use cases - Services

Use case diagram dat de interactie met de gebruikers modelleert tot aan de services.

In dit voorbeeld zijn alle gele use cases client facing, en representeren de rode use case de interactie met de service verlenende systemen.

Daarnaast modelleren we een tweede smart use case diagram, met de desbetreffende service, en alle achterliggende services als fish level use cases. In dit diagram beschrijft de sea level use case in het algemeen de orchestratie, en representeren de achterliggende fish level use cases de individuele services.

Smart use-case diagram - Leveren verlening VDU-ROS

Use case diagram dat het uitvoeren van de service Leveren Product modelleert.

In bovenstaand diagram  wordt de orchestratie verzorgd door de use case Leveren Product (via SAP middleware), en leveren de overige use cases services die door door Leveren Product worden geconsumeerd. In feite is deze use case een samengestelde service, die (letterlijk) wordt hergebruikt in het front end use case diagram, vergelijkbaar met de rode use cases in het voorgaande voorbeeld.

Het toepassen van een dergelijke aanpak biedt zeer concrete voordelen:

  • Eenduidig. Er is een eenduidige manier voor het beschrijven en modelleren van alle functionele onderdelen van het project, inclusief de schermen, orchestratie en services.
  • Gelijke granulariteit. Wanner het project de hierboven beschreven richtlijnen correct toepast, hebben alle use cases een vergelijkbare granulariteit – ze zijn allemaal ongeveer even groot, of zo u wilt, even klein.
  • Technologie-onafhankelijk. Smart use cases zijn te modelleren onafhankelijk van de platforms en technologie die wordt gebruikt. Bovenstaande voorbeelden kunnen evengoed in .NET en SAP worden gerealiseerd, als in in Java en Oracle.
  • Inschatbaar. De smart use cases, met daarbij de onderkende stereotypen, maken een goede eenheid voor het inschatten van servicegeorienteerde projecten. Hiervoor is een eenvoudige schaal gedefinieerd die wordt uigedrukt in smart use case punten.
  • Goede eenheid van werk.  Tenslotte, smart use cases vormen een goede eenheid van werk in projecten. In de regel is iedere use case los van de andere te ontwerpen, te ontwikkelen en vooral: individueel te testen. Met name dit laatste aspect zorgt ervoor dat de acceptatie van de te ontwikkelen en hergebruiken componenten vergemakkelijkt.
  • Hergebruik. Omdat smart use cases technologie-onafhankelijk zijn te modelleren en te beschrijven, biedt de techniek de mogelijkheid om een repository aan te leggen van gebruikte services, uitgedrukt in smart use cases.

Schatten met smart use cases

Omdat smart use cases zo eenduidig en technologie-onafhankelijk beeld geven van de functionaliteit van een project, is het een goede eenheid om de complexiteit en omvang van het project in te schatten. Hiervoor is een eenvoudige schaal gedefinieerd; de meetlat waarlangs alle smart use cases in een project wordt gelegd. Deze schaal is als volgt gedefinieerd:

  • 1 – Piece of cake. Eenvoudige use cases, zoals selecties uit standaardlijstjes, of eenvoudige onderhoud, zoals Onderhouden Contracttypen.
  • 2 – Moderate. Reguliere use cases, bijvoorbeeld voor selecties uit iets uitgebreidere lijstjes. Denk hierbij aan Selecteren Account Manager per Regio.
  • 3 – Average. De gemiddelde complexiteit, die meestal wordt gegeven voor regulier onderhoud, zoeken, of eenvoudige rapportages. Voorbeelden zijn Zoeken Boek, of Beheren Klant. Dit is tevens de default complexiteit.
  • 4 – Hard. Wordt gegeven bij lastiger onderhoud of rapportages. Ook eenvoudige services, meestal zonder het wegschrijven van gegevens, krijgen vaak deze complexiteit. Denk aan Ophalen Contract of Overzicht Orders per Klant.
  • 5 – Very difficult. Use cases met deze complexiteit worden als lastig beschouwd. Meestal zijn dit uitgebreide rapportages, grafieken, al dan niet met drill-down, of complexere services waarbij gegevens worden weggeschreven. Denk aan Vastleggen Abonnement.
  • 8 – Extreme, but known. Deze complexiteit wordt bewaard voor de zeer lastige use cases. Het betreft hier bijvoorbeeld complexe berekeningen of samengestelde services die vaak het uitvoeren van een proces voor hun rekening nemen. In business intelligence projecten wordt deze complexiteit vaak gegeven aan use cases die datatransformaties uitvoeren. Denk maar aan Berekenen Prepensioen.
  • 10 – Extreme and unknown. Deze hoogste complexiteit wordt uitgedeeld om twee redenen. Enerzijds voor use cases die bewezen lastig zijn, zoals het importeren en exporteren van bestanden en berichten. Anderzijds geven we deze complexiteit op het moment dat we wel weten dat de use case complex is, maar nog niet goed kunnen definieren hoe complex dit precies is. In deze gevallen verplichten we ons deze use case nog nader onder de loup te nemen. Vaak komen hier nog additionele use cases uit naar voren.

Met behulp van deze snel toepasbare schaal, en de vele standaardtypen use cases die we in veel projecten zijn tegengekomen en die al eerder langs deze maatlat zijn gelegd, kunnen we snel en betrouwbaar de complexiteit van een project inschatten. Dit maakt smart use case schattingen herhaalbaar, en bovendien kunnen er gemakkelijk ervaringscijfers uit worden gedistilleerd voor komende projecten. Dit laatste is met name in organisaties die servicegeorienteerd gaan werken belangrijk, omdat daar meerdere automatiseringprojecten uitvoeren binnen eenzelfde programma. Ons huidige project beslaat 298 smart use case punten.

Niet zelden komen dit soort schattingen tot stand tijdens workshops, waaraan alle betrokken partijen deelnemen, zoals de klant, de gebruikers, de architect, analisten, ontwikkelaars en ook de testers.

IMG_0224

Workshop waarin de complexiteit van smart use cases door het team wordt geschat

Tijdens dergelijke workshops krijgt het (toekomstige) projectteam een goed en vooral eenduidig beeld van het project en de complexiteit van de requirements. Met name voor de klant, die niet altijd een reeel beeld heeft hoe complex de realisatie van zijn of haar wensen eigenlijk is. “Oei. Dit wordt toch veel lastig en duurder dan we hadden verwacht,” is een veel gehoorde uitspraak, “misschien moesten we eens onderzoeken of er alternatieven zijn.”

Verlengen voordeeluren

Vooruit dan. Om mijn bovenstaande beweringen kracht bij te zetten een laatste anecdote. Tijdens een recent project bij een grote openbaar vervoersonderneming realiseerden we een aantal bedrijfsprocessen rondom een nieuw type abonnement. Deze processen waren uitgemodelleerd in smart use case diagrammen, zowel voor de front end als voor de services.

Ongeveer halverwege het project, terwijl we inmiddels al een deel van de processen hadden geimplementeerd als smart use cases, kwam de opdrachtgever schoorvoetend met een verzoek. “Zouden we, als we toch ook dit nieuwe type abonnement implementeren, ook eens kunnen kijken naar het verlengen van de voordeelurenkaarten?” Bijna verschoot de opdrachtgever hierbij van kleur.

Vrijwel onmiddelijk organiseerde de projectleider een workshop waarin het verlengen van voordeelurenkaarten onder de loup werd genomen. Na twee uur modelleren bleek dat bijna het gehele proces was te realiseren door hergebruik van smart use cases die we al hadden. We hoefden slechts vier nieuwe smart use cases toe te voegen, met een geschat totaal van 16 smart use cases punten. Het behoeft denk ik verder weinig uitleg dat de klant snel besloot het verlengen van de voordeelurenkaarten toe te voegen aan het project. Dit is hergebruik ten top.

Inzicht en overzicht

Servicegeorienteerde projecten kunnen, met name in grote organisaties, enorm bijdragen aan de effectiviteit en efficientie van de bedrijfsvoering. Een mooi voorbeeld hiervan maakte ik bij een bank mee. Wanneer een klant van deze bank het onzalige besluit nam om te verhuizen, moest dit oorspronkelijk in 36 verschillende systemen worden vastgelegd. Door steeds meer van deze systemen met behulp van services te ontsluiten, werd dit ogenschijnlijk eenvoudige bedrijfsproces in de loop van enkele jaren en projecten teruggebracht naar een enkele administratieve handeling.

Servicegeorienteerde projecten zijn echter ook zeer complex van aard. Bovengenoemde bank had een aantal projecten nodig om de beoogde verandering te bewerkstelligen. Alhoewel smart use cases, en de bijbehorende standaardtypen en schattingstechnieken natuurlijk niet alle problematiek van dit soort projecten tot nul reduceert, dragen ze zeer concreet bij aan het inzichtelijk maken van deze complexiteit, door een eenduidige eenheid van werk te introduceren, zowel voor de front ends, als voor de achterliggende orchestratie en services. Als klapper op de vuurpijl is deze uniforme eenheid van werk ook nog eens naar behoren in te schatten, en onafhankelijk te testen. Als ik het In een notedop zou moeten samenvatten: inzicht en overzicht. Precies dat wat veel servicegeorienteerde projecten ontberen.

Serviceorientatie vormgeven met smart use cases [In Dutch]

This post was originally written to be published as a chapter in an upcoming book on IT architecture. The book will be presented at the Landelijk Architectuur Congres 2009 in Nieuwegein, The Netherlands. This post will likely also be published in two parts in Software Release Magazine.

Ondanks dat ik inmiddels al zo’n twintig jaar in dit vakgebied rondloop, blijven software development projecten uitdaginen opleveren. Zo werkte ik eerder dit jaar coach aan een agile project waarmee een grote logistieke onderneming nieuwe producten voor hun klanten ontsloot.

Alhoewel ik vooral als coach was ingezet op het begeleiden van het proces, was het project technologisch een hele kluif. Een Java portal als front end, orchestratie van processen in SAP middleware, back office systemen in PeopleSoft, SAP en .NET die moesten worden “verserviced”, en niet te vergeten een aantal interfaces naar externe systemen, waar we niet of nauwelijks invloed op konden uitoefenen. Al met al een typisch voorbeeld van een service georienteerd project. Dit type projecten kenmerkt zich door hun hoge complexiteit, en zijn daarom slecht in te schatten en te plannen. Alhoewel niet de oplossing voor alle uitdagingen, bestaat er een techniek die smart use cases wordt genoemd, die concreet en pragmatisch bijdraagt aan het beter inschatten, plannen, maar ook realiseren en testen van servicegeorienteerde projecten.

Service georienteerde projecten zijn complex

Iedereen die in dergelijke projecten heeft gewerkt, weet het inmiddels wel: service georienteerde architecturen maken het uitvoeren van dit soort projecten er niet makkelijker op. Dit soort projecten kenmerken zich een groot aantal organisatorisch, functioneel en technisch complicerende factoren:

  • Diverse stakeholders. Servicegeorienteerde projecten automatiseren in het algemeen bedrijfsprocessen, die meestal meerdere organisatorische eenheden en verschillende systemen doorsnijden. Dientengevolge zijn er vaak diverse stakeholders betrokken bij het project.

IMAG00713

Een servicegeorienteerd project kent vele stakeholders

  • Flexibele front end technologien. Voor het realiseren of uitbreiden van de front end(s) wordt vaak gebruik gemaakt van state-of-the-art, of zelfs bleeding edge technologie, waarover niet altijd evenveel kennis beschikbaar is in de organisatie.
  • Heterogene back end technologien. De diverse systemen die ontsloten dienen worden – verserviced – zijn gerealiseerd in allerhande technologien, al dan niet verouderd.
  • Externe interfaces. Niet zelden wordt ook gebruik gemaakt van systemen die extern zijn aan de organisatie. Op deze systemen kan het project meestal weinig invloed uitoefenen, hooguit zijn de interfaces bekend. Helaas zijn dit soort interfaces zelden stabiel, en aan wijzigingen onderhevig.
  • Diverse rollen. Opvallend aan service georienteerde projecten is dat er een breed scala aan rollen betrokken is. Zo zorgt de diversiteit aan technologie al voor een breed palet aan developers – zo is een SAP CRM consultant geen SAP XI developer, en een .NET developer niet per se ook een software architect. Maar ook andere traditionele en minder traditionele rollen al informatie-analisten, ontwerpes, user inferface designers, enterprise architecten, business consultants en last but not least project managers, vinden hun weg in dit type projecten.

Service georienteerde projecten zijn lastig te plannen

Een recent voorbeeld is een project voor een verzekeraar voor het realiseren van een nieuw hypotheekoffertesysteem. Belangrijkste streven bij dit project was het realiseren van straight-through processing (het zonder humane tussenkomst doorvoeren van hypotheekoffertes naar de back office) en het flexibel kunnen toevoegen van nieuwe hypotheekproducten.

Naast de haast traditionele handicaps als schuivende requirements, bleek gedurende het project dat de interfaces van externe systemen niet aansloten op de gegevens die nodig waren om de benodigde processen uit te voeren. Daarnaast bleek ook de gebruikersvriendelijkheid van de (gegenereerde) webpagina’s tot hoofdbrekens te leiden. Het project levert nu hopelijk ruim een jaar na dato op, en heeft ruim vier keer zoveel gekost als oorspronkelijk begroot.

Maar waarschijnlijk vertel ik u als lezer hiermee nog niets nieuws. Lastig is wel dat deze complexiteit voor uw project een aantal ondermijnende gevolgen kan hebben. Om u een indruk te geven laat ik er hier toch maar een paar de revue passeren:

  • Externe afhankelijkheden. Service georienteerde projecten zijn vrijwel zonder uitzondering afhankelijk van derden, ofwel partijen binnen de eigen organisatie die andere planningen er op nahouden, ofwel partijen buiten de eigen organisatie, die lastig beinvloedbaar zijn.
  • Moeilijk in te schatten. Wie al eens in een offertetraject voor een dergelijk project heeft geparticipeerd; het maken van een goede schatting is cruciaal maar extreem lastig.
  • Moeilijk te plannen. Lastige schattingen, diverse stakeholders, externe afhankelijkheden, en talrijke projectrollen maken het er niet makkelijker op voor de beoogd project manager om een goed planning voor het project af te leveren.
    Een ding is zeker: een traditionele lineaire aanpak, waarin flexibiliteit tot een minimum wordt beperkt, is uit den boze. Een service georienteerd project kent vele wendingen – steeds meer overigens naarmate het project langer duurt.

Het zal u niet verbazen dat met deze consequenties service georienteede projecten te vaak niet op tijd en op budget worden opgeleverd, of dat gaandeweg het project wordt besloten slechts een deel van de vereiste functionaliteit op te leveren. Tenslotte worden de beoogde uitgangspunten voor het project vaak niet gehaald. Denk daarbij aan het in service ontsluiten van legacy back end systemen, het realiseren  van hergebruik ten einde toekomstige projecten sneller te kunnen uitvoeren, het opbouwen van een repository van services or het snel en flexibel kunnen toevoegen van nieuwe producten en features.

Hoe complex is het project eigenlijk?

Zoals gezegd zijn service georienteerde projecten meestal lastig te schatten en derhalve nog lastiger te plannen. Een belangrijk vraag die bij aanvang van dit soort projecten dan ook dient te worden gesteld om een goede kosten-baten-analyse te kunnen maken is: hoe groot en complex is ons project nu eigenlijk?

Een belangrijk struikelblok bij het beantwoorden van deze op het oog eenvoudige vraag is dat er allerlei verschillende typen deliverables zijn te onderkennen in een service georienteerd project. Denk hierbij bijvoorbeeld maar aan webpagina’s, schermen, services, orchestratie, domeinobjecten, transacties. Dit maakt het “tellen” van de totale complexiteit van een project lastig. En zelfs wanneer al deze verschillend typen deliverables zouden kunnen worden geteld, dan nog ontbreken er de nodige ervaringscijfers, die de uiteindelijke complexiteit per type deliverable in uren kunnen helpen vertalen.

IMG_02424

Smart use cases modelleren in een servicegeorienteerd project

Het zou een belangrijk stap voorwaarts voor servicegeorienteerde projecten kunnen zijn wanneer alle (functionele) deliverables op een en dezelfde schaal konden worden uitgedrukt, waarbij de complexiteit van zowel de webpagina’s, schermen, orchestratie als services op eenzelfde manier wordt uitgedrukt, middels een enkele eenheid van schatten, en misschien zelfs wel een enkele eenheid van werk. Immers, zo kunnen makkelijker ervaringscijfers worden verzameld, die weer kunnen worden toegepast om volgende projecten binnen hetzelfde programma beter in te plannen. Deze eenheid van werk dient zich aan door smart use cases te introduceren in service georienteerde projceten.

Use cases

Laat ik bij het begin beginnen. Wat zijn eigenlijk use cases? Meestal wordt een use case aangemerkt als een beschrijving van het gedrag dat software vertoont als reactie op een verzoek dat stamt van buiten de software. Vrij vertaald beschrijft een use case wie met de software wat kan doen. Een use case realiseert een bepaald doel voor uitvoerder van de use case. In jargon wordt deze uitvoerder wel de actor genoemd. Zo’n actor hoeft overigens niet perse menselijk te zijn, maar kan bijvoorbeeld ook andere software zijn of zelfs een batchverwerking.

Het uitvoeren van de use case vindt plaats als een opeenvolging van een aantal stappen. Deze stappen vormen tesamen een of meerdere scenario’s die uitmonden of in het realiseren van het doel, of, wanneer er iets mis gaat, in een uitzonderingssituatie. Deze eindresultaten worden wel de postcondities van de use cases genoemd. Use cases worden veelal beschreven in documenten, al dan niet geformateerd in een voorgeschreven sjabloon.

ManageSite3

Voorbeeld van een use case diagram

Daarnaast bestaat er een aardige, relatief informele en veel toegepast modelleertechniek, waarin actor als poppetjes worden gerepresenteerd, en use cases als ovaaltjes. Deze modelleertechniek, die het use case diagram wordt genoemd, wordt ondersteund door een breed scala aan geautomatiseerde gereedschappen.

Traditionele use cases

Traditioneel worden reguliere use cases gebruikt voor het beschrijven van de functionele requirements van een regulier project, uitgaande van het doel dat de gebruiker (of actor) wil bereiken door de use case uit te voeren. Traditioneel worden use cases beschreven in een document, dat naast het doel, het resultaat ook alle mogelijke scenario’s beschrijft aan de hand waarvan de use case kan worden doorlopen.

Een interessant voorbeeld van een dergelijk use case kwam ik tegen in een service georienteerde project bij een interrnationale bank, waar een use case Wijzigen Adres een document van vijfenzestig pagina’s besloeg, waarin twaalf schermen voorkwamen, tientallen scenario’s en waarin diverse services werden aangeroepen. Een ander gelijksoortig voorbeeld is een use case Uitvoeren Kwartaalfacturering van een pensioenfonds, waarbij circa 1.3 miljoen factuurregels werden berekend.

Alhoewel dergelijke use cases  in service georienteerde meestal de te realiseren bedrijfsprocessen beschrijven, zijn ze niet bijzonder geschikt als eenheid van werk en van schatten in dit type projecten. Traditionele use cases verschillen te veel in omvang en complexiteit, om ze met een gerust hart op een lineare schaal uit te drukken. Ter ondersteuning: het realiseren van de use case Uitvoeren Kwartaalfacturering vergde ruim anderhalf jaar, terwijl het in hetzelfde project slechts enkele dagen kostte de use case Inloggen Gebruiker in te voeren.

Daarbij komt nog het bezwaar dat deze wijze van benaderen van use cases niet bijdraagt aan het identificeren en realiseren van de gewenste services, en dat hergebruik slechts sporadisch en incidenteel tot stand komt.

Smart use cases

Toch hebben we in de afgelopen jaren ervaren dat use cases een heel nuttig vehikel kunnen zijn in servicegeorienteerde projecten. En niet alleen om projecten in te kunnen schatten, maar ook als eenheid van werk, en zelfs voor het identificeren en hergebruiken van services. Om deze nobele doelstellingen te bereiken maken we intensief gebruik van wat we in de loop der jaren smart use cases zijn gaan noemen – genoemd naar de agile methodiek Smart en goed beschreven in mijn boek Pragmatisch modelleren met UML. Een korte introductie.

Alistair Cockburn, autoriteit op het gebied van use cases, beschrijft in zijn boek Writing effective use cases een model waarin use cases in vijf verschillende niveau’s van granulariteit – zeg maar grootte en complexiteit – worden uitgedrukt.

image3

Deze niveau’s zijn:

  • Cloud. Use cases op dit hoogste niveau representeren veelal groepen van samenhorende bedrijfsprocessen, zoals Verkopen Producten.
  • Kite. Op dit tweede niveau worden in de regel individuele bedrijfsprocessen geposteerd, vaak workflow georienteerd.
  • Sea. Dit is het niveau waar het om draait, en waar bijvoorbeeld ook Wijzigen Adres toe behoort. De kernvraag op dit niveau zou kunnen zijn: hangt de performance van mijn organisatie af van hoeveel van deze kan ik per dag uitvoeren? Als richtlijn: deze use cases komen nagenoeg overeen met wat ook wel als elementaire bedrijfsprocessen wordt geduid.
  • Fish. Use cases op fish niveau worden gebruikt om op zichzelfstaande, maar aan sea niveau ondersteunende functionaliteit te modelleren. Denk bijvoorbeeld aan Ophalen Abonnement of Selecteren Product.
  • Clam. Soms modelleren projecten te ver door, en worden de use cases te klein. Hier spreekt men over clam niveau.

Ondanks de beknoptheid van deze introductie, moge het duidelijk zijn dat cloud en kite niveau in servicegeorienteerde project met name terug te vinden zijn in de te automatiseren bedrijfsprocessen, de visie van het projec en wellicht de bedrijfsarchitectuur van de organisatie.

De use cases op het sea en fish niveau worden samen smart use cases genoemd. Deze twee niveau’s vormen zo een goede basis van gelijke granulariteit zowel voor het uitdrukken van functionaliteit die direct zichtbaar is voor de gebruiker, zoals Selecteren Product, maar ook voor het identificeren van services, en het aanleggen van een repository van deze services, zoals Ophalen Abonnement.

Smart use cases modelleren

Veel meer dan in traditionele use cases het geval is, gebruiken we voor het vormgeven van smart use cases de bijbehorende modelleertechniek.

Uitgaande van de lijst te realiseren bedrijfsprocessen op kite niveau, modelleren we een use case diagram per elementair bedrijfsproces, op sea niveau derhalve. Ieder use case diagram bevat:

  • Sea niveau use case. Een enkele use case die het elementair bedrijfsprocess representeert, weergegeven als een ovaal.
  • Actoren. Een of meerdere partijen die gebruik maken van deze use case, om daar hun doel mee te bereiken, weergegeven als poppetjes.
  • Fish niveau use cases. Nul, een of meerdere use cases die ondersteunend zijn aan de sea niveau use case, eveneens weergegeven als ovalen.

Onderstaande figuur bevat een goed voorbeeld van een dergelijke use case diagram .

Task4

In dit use case diagram zijn de use cases Apply for Membership en Activate Membership sea nieuws use cases, de overige use cases zoals Send Confirmation en Validate Creditcard zijn fish niveau.

Om tot dit diagram te komen distilleren we normaliter de fish niveau use cases uit de sea niveau use case, door onszelf steeds opnieuw te vragen: wat is de volgende stap die we nemen bij het uitvoeren van deze use case? In sommige gevallen is het handig om deze stappen als individuele use cases op te nemen in het diagram, in andere gevallen weer niet. We hanteren hiervoor een set aan richtlijnen, zoals aan het identificeren van hergebruik – komen we deze use case mogelijk vaker tegen? Of denk het afhandelen van alle interactie rond een formulier of scherm, of het importeren en exporteren van bestanden.

Standaard typen smart use cases

Deze hierboven beschreven aanpak is inmiddels – met veel succes – toegepast in een diverse typen projecten, zoals reguliere webprojecten in .NET of Java, het implementeren van portals, business intelligence en zelfs pakketimplementaties.

Bij het uitvoeren van al deze projecten is vooral opgevallen dat steeds opnieuw dezelfde soorten smart use cases de revue passeren. Denk hierbij aan het selecteren, zoeken, of onderhouden van gegevens, het exporteren van een bestand, of het aggregeren van gegevens in een business intelligence situatie.

Deze standaardtypen use cases (in de wandelgangen stereotypen genoemd) helpen projecten enorm om de analyse van de requirements te versoepelen en standardiseren. Het jargon van smart use cases wordt tijdens workshops al snel overgenomen door opdrachtgever en gebruikers. “Ik stel voor dat hier hier een master-detail over klanten en orders gebruiken, met een search op producten”.

Belangrijk bijkomende voordelen van het toepassen van deze (of eigen) stereotypen is dat ook het schatten van de omvang van het project vergemakkelijkt, en dat ook de realisatie, inclusief testen, van dit soort standaard use cases eenvoudiger is. Immers, er is al eens eerder met hetzelfde bijltje gehakt. Een onderhouds-use case voor klanten verschilt niet wezenblijk van een onderhouds-use case voor producten.

Smart use cases modelleren in servicegeorienteerde projecten

Ook in servicegeorienteerde projecten hanteren we sinds enkele jaren smart use cases. Daarbij brengen we graag een tweedeling aan, we modelleren een front end use case diagram, en een service use case diagram.

Allereerst modelleren we een smart use case diagram vanaf de sea level use case die de interactie met de gebruikers en het elementaire bedrijfsproces vertegenwoordigt, zoals Aanvragen Subsidie. Daarbij identificeren we de bijbehorende fish level use cases, maar alleen  tot aan het aanroepen van de services of de orchestratie.

SmartusecasesServices

Use case diagram dat de interactie met de gebruikers modelleert tot aan de services.

In dit voorbeeld zijn alle gele use cases client facing, en representeren de rode use case de interactie met de service verlenende systemen.

Daarnaast modelleren we een tweede smart use case diagram, met de desbetreffende service, en alle achterliggende services als fish level use cases. In dit diagram beschrijft de sea level use case in het algemeen de orchestratie, en representeren de achterliggende fish level use cases de individuele services.

SmartusecasediagramLeverenverleningV

Use case diagram dat het uitvoeren van de service Leveren Product modelleert.

In bovenstaand diagram  wordt de orchestratie verzorgd door de use case Leveren Product (via SAP middleware), en leveren de overige use cases services die door door Leveren Product worden geconsumeerd. In feite is deze use case een samengestelde service, die (letterlijk) wordt hergebruikt in het front end use case diagram, vergelijkbaar met de rode use cases in het voorgaande voorbeeld.

Het toepassen van een dergelijke aanpak biedt zeer concrete voordelen:

  • Eenduidig. Er is een eenduidige manier voor het beschrijven en modelleren van alle functionele onderdelen van het project, inclusief de schermen, orchestratie en services.
  • Gelijke granulariteit. Wanner het project de hierboven beschreven richtlijnen correct toepast, hebben alle use cases een vergelijkbare granulariteit – ze zijn allemaal ongeveer even groot, of zo u wilt, even klein.
  • Technologie-onafhankelijk. Smart use cases zijn te modelleren onafhankelijk van de platforms en technologie die wordt gebruikt. Bovenstaande voorbeelden kunnen evengoed in .NET en SAP worden gerealiseerd, als in in Java en Oracle.
  • Inschatbaar. De smart use cases, met daarbij de onderkende stereotypen, maken een goede eenheid voor het inschatten van servicegeorienteerde projecten. Hiervoor is een eenvoudige schaal gedefinieerd die wordt uigedrukt in smart use case punten.
  • Goede eenheid van werk.  Tenslotte, smart use cases vormen een goede eenheid van werk in projecten. In de regel is iedere use case los van de andere te ontwerpen, te ontwikkelen en vooral: individueel te testen. Met name dit laatste aspect zorgt ervoor dat de acceptatie van de te ontwikkelen en hergebruiken componenten vergemakkelijkt.
  • Hergebruik. Omdat smart use cases technologie-onafhankelijk zijn te modelleren en te beschrijven, biedt de techniek de mogelijkheid om een repository aan te leggen van gebruikte services, uitgedrukt in smart use cases.

Schatten met smart use cases

Omdat smart use cases zo eenduidig en technologie-onafhankelijk beeld geven van de functionaliteit van een project, is het een goede eenheid om de complexiteit en omvang van het project in te schatten. Hiervoor is een eenvoudige schaal gedefinieerd; de meetlat waarlangs alle smart use cases in een project wordt gelegd. Deze schaal is als volgt gedefinieerd:

  • 1 – Piece of cake. Eenvoudige use cases, zoals selecties uit standaardlijstjes, of eenvoudige onderhoud, zoals Onderhouden Contracttypen.
  • 2 – Moderate. Reguliere use cases, bijvoorbeeld voor selecties uit iets uitgebreidere lijstjes. Denk hierbij aan Selecteren Account Manager per Regio.
  • 3 – Average. De gemiddelde complexiteit, die meestal wordt gegeven voor regulier onderhoud, zoeken, of eenvoudige rapportages. Voorbeelden zijn Zoeken Boek, of Beheren Klant. Dit is tevens de default complexiteit.
  • 4 – Hard. Wordt gegeven bij lastiger onderhoud of rapportages. Ook eenvoudige services, meestal zonder het wegschrijven van gegevens, krijgen vaak deze complexiteit. Denk aan Ophalen Contract of Overzicht Orders per Klant.
  • 5 – Very difficult. Use cases met deze complexiteit worden als lastig beschouwd. Meestal zijn dit uitgebreide rapportages, grafieken, al dan niet met drill-down, of complexere services waarbij gegevens worden weggeschreven. Denk aan Vastleggen Abonnement.
  • 8 – Extreme, but known. Deze complexiteit wordt bewaard voor de zeer lastige use cases. Het betreft hier bijvoorbeeld complexe berekeningen of samengestelde services die vaak het uitvoeren van een proces voor hun rekening nemen. In business intelligence projecten wordt deze complexiteit vaak gegeven aan use cases die datatransformaties uitvoeren. Denk maar aan Berekenen Prepensioen.
  • 10 – Extreme and unknown. Deze hoogste complexiteit wordt uitgedeeld om twee redenen. Enerzijds voor use cases die bewezen lastig zijn, zoals het importeren en exporteren van bestanden en berichten. Anderzijds geven we deze complexiteit op het moment dat we wel weten dat de use case complex is, maar nog niet goed kunnen definieren hoe complex dit precies is. In deze gevallen verplichten we ons deze use case nog nader onder de loup te nemen. Vaak komen hier nog additionele use cases uit naar voren.

Met behulp van deze snel toepasbare schaal, en de vele standaardtypen use cases die we in veel projecten zijn tegengekomen en die al eerder langs deze maatlat zijn gelegd, kunnen we snel en betrouwbaar de complexiteit van een project inschatten. Dit maakt smart use case schattingen herhaalbaar, en bovendien kunnen er gemakkelijk ervaringscijfers uit worden gedistilleerd voor komende projecten. Dit laatste is met name in organisaties die servicegeorienteerd gaan werken belangrijk, omdat daar meerdere automatiseringprojecten uitvoeren binnen eenzelfde programma. Ons huidige project beslaat 298 smart use case punten.

Niet zelden komen dit soort schattingen tot stand tijdens workshops, waaraan alle betrokken partijen deelnemen, zoals de klant, de gebruikers, de architect, analisten, ontwikkelaars en ook de testers.

IMG_02243

Workshop waarin de complexiteit van smart use cases door het team wordt geschat

Tijdens dergelijke workshops krijgt het (toekomstige) projectteam een goed en vooral eenduidig beeld van het project en de complexiteit van de requirements. Met name voor de klant, die niet altijd een reeel beeld heeft hoe complex de realisatie van zijn of haar wensen eigenlijk is. “Oei. Dit wordt toch veel lastig en duurder dan we hadden verwacht,” is een veel gehoorde uitspraak, “misschien moesten we eens onderzoeken of er alternatieven zijn.”

Verlengen voordeeluren

Vooruit dan. Om mijn bovenstaande beweringen kracht bij te zetten een laatste anecdote. Tijdens een recent project bij een grote openbaar vervoersonderneming realiseerden we een aantal bedrijfsprocessen rondom een nieuw type abonnement. Deze processen waren uitgemodelleerd in smart use case diagrammen, zowel voor de front end als voor de services.

Ongeveer halverwege het project, terwijl we inmiddels al een deel van de processen hadden geimplementeerd als smart use cases, kwam de opdrachtgever schoorvoetend met een verzoek. “Zouden we, als we toch ook dit nieuwe type abonnement implementeren, ook eens kunnen kijken naar het verlengen van de voordeelurenkaarten?” Bijna verschoot de opdrachtgever hierbij van kleur.

Vrijwel onmiddelijk organiseerde de projectleider een workshop waarin het verlengen van voordeelurenkaarten onder de loup werd genomen. Na twee uur modelleren bleek dat bijna het gehele proces was te realiseren door hergebruik van smart use cases die we al hadden. We hoefden slechts vier nieuwe smart use cases toe te voegen, met een geschat totaal van 16 smart use cases punten. Het behoeft denk ik verder weinig uitleg dat de klant snel besloot het verlengen van de voordeelurenkaarten toe te voegen aan het project. Dit is hergebruik ten top.

Inzicht en overzicht

Servicegeorienteerde projecten kunnen, met name in grote organisaties, enorm bijdragen aan de effectiviteit en efficientie van de bedrijfsvoering. Een mooi voorbeeld hiervan maakte ik bij een bank mee. Wanneer een klant van deze bank het onzalige besluit nam om te verhuizen, moest dit oorspronkelijk in 36 verschillende systemen worden vastgelegd. Door steeds meer van deze systemen met behulp van services te ontsluiten, werd dit ogenschijnlijk eenvoudige bedrijfsproces in de loop van enkele jaren en projecten teruggebracht naar een enkele administratieve handeling.

Servicegeorienteerde projecten zijn echter ook zeer complex van aard. Bovengenoemde bank had een aantal projecten nodig om de beoogde verandering te bewerkstelligen. Alhoewel smart use cases, en de bijbehorende standaardtypen en schattingstechnieken natuurlijk niet alle problematiek van dit soort projecten tot nul reduceert, dragen ze zeer concreet bij aan het inzichtelijk maken van deze complexiteit, door een eenduidige eenheid van werk te introduceren, zowel voor de front ends, als voor de achterliggende orchestratie en services. Als klapper op de vuurpijl is deze uniforme eenheid van werk ook nog eens naar behoren in te schatten, en onafhankelijk te testen. Als ik het In een notedop zou moeten samenvatten: inzicht en overzicht. Precies dat wat veel servicegeorienteerde projecten ontberen.

October 20. Talk. “Shaping service oriented projects using smart use cases”

SDC Conference, Papendal, Arnhem (www.sdc.nl)

Next week the annual SDC conference will take place at Papendal, Arnhem. As usual the organising SDN community has put together a long list of international appraised speakers, and challenging subjects on the matter of software development and software architecture.

Smart use-case model - Verlengen VDU 

A bit to my surprise, this year I was invited to do 3 talks, with very different subjects: Silverlight and code generation, smart use cases in service oriented projects, and .NET extension methods.

My talk on smart use cases will deal with the difficulties service oriented projects have, how identifying and modeling smart use cases from a variety of sources can help, and how to model and estimate services in a service oriented environment using smart use cases. Alas, no code!

Service orientation and smart use cases

The SDC website refers to my talk on smart use cases as follows:

Although many organizations apply service oriented architecture at the core of their software development efforts, executing such projects is hard. There are many different stakeholders, even external to the organization. And then there are many different types of deliverables.

Legacy code needs to be wrapped, services need to be identified and defined, workflow needs to be modeled, user interface navigation decided, cloud computing needs to be researched. And if that wasn’t enough to make a grown man sweat, try estimating the size and complexity of these often multi man month projects.

Read more: Sander at SDC 2009.

October 19. Talk. “Silverlight, .NET RIA Services and code generation”

SDC Conference, Papendal, Arnhem (www.sdc.nl)

Next week the annual SDC conference will take place at Papendal, Arnhem. As usual the organising SDN community has put together a long list of international appraised speakers, and challenging subjects on the matter of software development and software architecture.

SONY DSC 

A bit to my surprise, this year I was invited to do 3 talks, with very different subjects: Silverlight and code generation, smart use cases in service oriented projects, and .NET extension methods.

Putting model driven development to the test

The SDC website refers to my Silverlight talk as follows:

To be quite honest, this talk is putting model driven development (MDD) to the test. Model driven development – generating code from a model – is a concept that has long promised high productivity and quality to projects. There are many different approaches to MDD, some of them highly theoretical, some of them painfully oversimplified. Think of generating code from UML models, or using Oslo and M. And whatever happened to (graphical and textual) DSL’s?

As always Sander and his team follow a very pragmatic, straightforward approach to the subject, generating code from domain models and smart use cases. One of the benefits of true model driven development is that it allows to generate code from the same model to different target environments. Having done projects where code was generated in Windows applications, ASP.NET applications, and Java web applications, Sander will now use this approach to Silverlight line-of-business applications. In this talk Sander elaborates on how code generation works, how templates can be defined for Tobago MDA, a freely available MDD code generators, and will (try to) build up a Silverlight applications on stage.

Introducing .NET RIA Services

Unfortunately, my team was minimized due to illness and projects, and I had to figure out most of it myself – a though late night job. Especially since I want to pay attention to .NET RIA Services, a brand new way of buidling client/server applications in a distributed environment, where a lot of code generation takes place under the covers.

Let’s just I I can do some demo’s on the 19th…

Read more: Sander at SDC 2009.

October 8-9, 2009. Workshop. “Pragmatic modeling using UML and beyond”

IT Works, Crowne Plaza Hotel, Antwerp, Belgium

I will present an intense two day workshop in the Crowne Plaza in Antwerp. During this workshop I follow the pragmatic modeling approach presented in my book with the same title. During this highly interactive workshop participants will learn how the various modeling techniques from UML and beyond connect.

image

Learn everything about (smart) use cases and start working directly with UML in many exercises a pragmatic case – Dare2Date, an online dating site.

Topics include: UML overview, an agile approach to requirements, modeling smart use cases, testing use cases (with activity diagrams), user interface modeling, domain modeling (using class diagrams), modeling services, interaction modeling (with sequence diagrams), modeling in agile software development projects, and model driven development using UML.

Participants will receive a copy of the book Pragmatic Modelling with UML 2.0. This workshop always gets rave reviews. Note that this is the 29th edition of my UML workshops at IT Works!

See www.itworks.be

image

Writing better software faster

Published in my Interesting Things column in SDN Magazine, November 2009.

Looking back on twenty years of software development, I must have spent most of that time trying to improve the quality and productivity of software development.

Ever since I started to write small applications in Turbo Pascal in 1988 I got infected with the writing-better-software-faster virus. Right after I finished the second of fourteen of these applications, I wrote my first framework. It took some effort, but writing the following twelve applications took me less time than building the first two.

Darkening perspectives

There are good reasons for increasing productivity and quality. First of all, we have to increase productivity by a hundred-fold to meet up with current demands, says Gartner. Furthermore, technology is becoming increasingly complex. Ten years ago I was working in both Microsoft and Java projects. Anno 2009, I’ve let go of the idea that I even have an overview of either one of them. It is hard enough working with a small subset of frameworks. A Silverlight designer is not likely knowledgeable in NHibernate. Being a Spring guru does not guarantee foxy JavaFX user interfaces.

Despite this darkening perspective, there’s techniques and technologies that might keep you from drowning, by simply raising the level of abstraction. Good frameworks help. Smart use cases certainly do. And even UML assists. And then there’s model driven development a.k.a. model driven architecture a.k.a. model driven engineering a.k.a. domain specific languages. Different names for generating code and other deliverables from a model. What model? To be honest, any model will do the trick. Business process models, use case diagrams, user interface models, domain models, and last but not least data models.

Empirical start

Eight years ago I was helping a customer set up the domain model for a help desk application. After that I started to build the software in ASP.NET. Having modeled all domain objects, their properties and their services, I was typing them out in C#. So, as any decent developer would do I wrote a code generator. That helped.

I suspect most code generation efforts have a similar empirical start. That’s probably why there are so many approaches to generating code. Some really high-brow, squeezing everything-and-the-kitchen-sink into a model, and then trying to generate the whole application. From front  to back. Or, at the very low and of the spectrum, inspecting the database, generating create-read-update-delete screens in a flat two-tier architecture.

Where’s the value?

Recently I was invited in a panel on model driven development, together with some academic and commercial experts. For starters, each of the panel members introduced their position briefly to the audience. This noteworthy event learned me two things. One: never allow four enthusiastic innovators talk freely on their innovations. The word brief isn’t in their vocabulary. Two: coming from a business background, I didn’t have a clue to what model driven development does in the academic world. A whole new spectrum of approaches met my eye.

clip_image001

So where’s the value in this? Following the good old Scrum adagio I’d say: it depends. Model driven development can be highly rewarding for projects. But I’ve also witnessed projects that made a terrible mess of it.

In my opinion, being successful at model driven development requires some preconditions to be met:

  • Embed approach. Successful model driven development projects share a single principle: it’s all in a day’s work. Model driven development is never a goal. It’s just a means to an end. Making better software faster. No guru’s, no heroes.

  • Allow changes. Projects go through changes. That’s a fact of life. Model driven development should never be blocking changes, but rather should stimulate creativity, by allowing projects to show quickly what effect new or changing requirements have.

  • Stabilize architecture. Knowing how to model, and where to generate what code is key. Set up a stable (layered) software architecture, pick frameworks that match it, and only then elaborate on code generation.

  • Be pragmatic. My general advice in life also holds for model driven development. Be pragmatic. Never overdo it. Don’t try to squeeze the whole world in your model. It’s not necessarily a bad thing to still have to write some code manually.

Skepticism?

Having said all that, and having seen projects that very successfully apply model driven development, why is there still so much skepticism? After all, the paradigm really helps to deliver high quality at high productivity.

After witnessing both highly successful and extremely failing model driven development projects recently, I have given this some consideration. The vast majority of projects are in the middle of the wide spectrum of approaches. They run smoothly, being fairly practical. But it’s the failing projects at either end of the spectrum that draw the attention. Highly complex, slow moving, rigor projects on the one end, and oversimplified, bug-absorbing, underestimated projects on the other end. It’s no fun at either end.

No Jedi knight

My team and I have always adopted a highly pragmatic approach to model driven development, modeling smart use cases, applying domain driven design, run the model through our code generators (Tobago MDA) and we’re set to go. We do make better software faster.

Can life be this simple? It certainly can. We have applied this approach to all kinds of projects, and generated code in a variety of languages and frameworks, from Visual Basic to C#, from PHP and Java to Cobol. At the upcoming SDC, I’m going the check out a combination of Silverlight, .NET RIA Services, ADF and probably Fluent NHibernate. Should be fun!

To leave you with some words of wisdom (ahum). If there’s one thing I’ve learned from being successful at model driven development, it’s this: modeling and generating code should be everyday practice in your project. There’s no such thing as a “model driven development project”. There’s only software development projects. You don’t have to be a Jedi knight to steer a code generator. It’s all in a day’s work.

Pragmatic model driven development. Part I. Code generation scenario’s

Note. This series of posts is also published as a Capgemini group white paper and published in Software Release Magazine (in Dutch, in two parts).

With the economy at a low point in time, organizations and project are clearly resetting their goals. Long term multimillion projects are being halted, in favor of short, agile projects, with feasible goals and good time-to-target. To realize these stringent goals, projects are striving for lower costs and higher productivity. On the one hand these goals might be reached by outsourcing, on the other hand standardization, industrialization and reuse could also contribute.

A long term promise in the field of increasing productivity and reuse is to handcraft less code, but to generate code from the project’s design or model. In general this is called model driven development

When is model driven development effective?

Although many alternative strategies exist towards model driven development, we feel that a pragmatic approach works best. The more theoretical an approach gets, the harder it is to apply it to projects. In this paper, we present such a highly pragmatic approach to model driven development. We model and standardize smart use cases and the domain model for a project, and generate code and other deliverables from these models using a straightforward tool set. This approach has proven to be very effective in many projects.

Model driven development can be effective when code and other deliverables can be generated rather than written or hand coded. Thus tedious repetitive work is avoided, such as creating web forms, user interface panels, domain objects, table create statements, service interfaces and even writing use case documentation. Developers can now focus on developing business logic, or tuning the user interface. We have witnessed very high productivity in projects that apply pragmatic model driven development. For example, a recent project (.Net) at a large Dutch government agency was realized in 20% of the time the customer estimated the project.

As it is also fairly easy to create new types of deliverables simply by investigating your existing code and derive template from this, we can save time and effort in many scenario’s and development environments. Model driven development has proven to be successful in (partly) generating solutions for various types of projects, including ASP.Net, Silverlight, SharePoint, Visual Basic Window Forms, Java, service oriented applications (.Net and SAP), and even back end functionality.

Moreover, as code generation is based on proven templates, generated code is of higher quality then hand written code. Thus, model driven development also contributes to lowering maintenance costs of delivered software. This effect is further increased because the documentation as presented in the model is directly traceable to the application’s code.

Last but not least, in model driven development, analysts and designer actively participate in delivering working software, as the models they help creating, are now directly converted into code. Model driven development is a collaborative scenario, where, especially in agile projects even end-users can participate directly in software development. To illustrate this, we usually model the smart use cases and the domain model that, underlie the software we produce, during interactive workshops with the end users, and generate working software either in these workshops, or shortly after.

IMG_0242[1]

Code generation scenario’s

Generating code from a model can be done in a wide variety of scenario’s, and with a even wider range of goals and deliverables to strive for:

  • Proprietary techniques. Traditionally there’s tools such as Oracle Designer and Developer or Cool:GEN that host both the model as the coding environment. Using these environment high productivity can be achieved, because a lot of assumptions can be made on the target environment. In general such development environments deliver highly proprietary models and code.
  • DSL’s. Domain Specific Language (DSL) are textual or visual representations of custom domains, for which specific modeling language can be defined, think of web service definition or even a language for defining the mortgages or life assurance domain. With DSL’s again has the promise of high productivity, if and only if, the target environment can be clearly defined, for instance in the software architecture and framework that are used.
  • UML. The Unified Modeling Language (UML) provides a set of techniques for modeling behavior and structure of applications. These standardized techniques, such as use case or class diagrams are used in projects around the world, however in different variations and dialects. Generating code or other deliverables from a UML model is highly possible, again if the target environment is well defined.
  • Database. With proper modeling techniques lacking, many tools take the approach of generating (parts of) applications from the database structure. Although this approach seems appealing and fast, there are limitations. The generated application will mimic the database, and thus will be very data-centric, instead of providing support for the work processes to be automated. Besides that, in the current era of service orientation and cloud computing, many application do not even have their own database.

SDN software architecture event 25 juni [in Dutch]

Speciaal voor Software Architects organiseert het SDN op donderdagavond 25 juni een SDN Event met twee hoogstaande sessies die architectects zeker zullen aanspreken. Het event vindt plaats in Hotel Houten (in Houten).

  • Sander Hoogendoorn doet zijn sessie: Navigeren door een woud van frameworks.
  • Edward Bakker en Clemens Reijnen presenteren: Architectural Inspections with VSTA2010 and Application Architecture Guidance V2.

Deze avond is voor deelnemers gratis toegankelijk. Je ontvangt dan tevens een gratis SDN lidmaatschap op persoonlijke titel dat je wordt aangeboden door Microsoft Nederland. Dit lidmaatschap is geldig tot en met 31 mei 2010 en eindigt dan automatisch zonder verdere verplichtigingen.

dsc-6268

Het programma:

  • 18:30u -19:00u
    Registratie en ontvangst
  • 19:00u – 20:00u
    Sander Hoogendoorn
    Navigeren door een woud van frameworks.
    Hoe frameworks een project om zeep kunnen helpen, en patronen om dit te voorkomen.
  • 20:00u – 20:30u
    Pauze
  • 20:30u – 21:30u
    Edward Bakker & Clemens Reijnen
    Architectural Inspections with VSTA2010 and Application Architecture Guidance V2

Kijk voor meer informatie en om in te schrijven hier: http://www.sdn.nl/arch_event

The days are just packed. My talks in May and June 2009

The months May and June are notorious for the number of talks – as Rick van der Lans describes: May and June are speaker’s season. Just to remind me not to forget any of my upcoming talks, here’s a list:

  • May 12. Project estimation with smart use cases. At Capgemini, Utrecht. Presentation at internal software estimation seminar for Community of Practice Methods & Tools.
  • May 13. Achieving business flexibility with smart use cases. Keynote at seminar on  business flexibility at Synobsis, Castle Lage Vuursche, Baarn. See www.synobsys.nl.
  • May 14. Estimating with smart use cases. Half-day seminar for Array Seminars, NBC Nieuwegein. See www.arrayseminars.nl.
  • May 25. An introduction to smart use cases. Presentation at Capgemini event for large customer, Utrecht.
  • May 26. Agile requirements and smart use cases. Half-day presentation at Capgemini BAS, Apeldoorn.
  • May 28. Navigating through the hypes. Software architectures and patterns to help avoiding your projects to crash. Interactive talk on frameworks and how they can kill your projects at Microsoft DevDays, Congrescentrum Den Haag. See www.devdays.nl.

DSC_6268

  • June 3. Agile software development in everyday practice. Full-day seminar on doing agile projects for IT Works, Hotel Pullman, Diegem, Belgium. With guest speaker Stefaan van Royen, Mediamine. See www.itworks.be.
  • June 9. Pragmatic .Net development. Full-day seminar on software architectures and patterns for .Net software development for Array Seminars, .NBC Nieuwegein. See www.arrayseminars.nl.
  • June 15 & 16. Smart use cases from front to back. Custom two-day interactive workshop for information and business analysts of large Capgemini client at Capgemini Papendorp, Utrecht. Includes introduction of smart use cases, estimating smart use cases, smart use cases in service oriented architecture, testing smart use cases, domain driven design, agile, Smart / Scrum.
  • June 18. Mission impossible? Introducing agile in service oriented SAP projects. Talk at Integrate Agile Conference with Twan van den Broek, Topforce, for the Agile Consortium Benelux, Claus, Badhoevedorp. I didn’t notice that I have a double booking until now… trying to solve it.
  • June 18 & 19. Pragmatic modeling using UML and beyond. Fully packed two-day workshop on UML, modeling, smart use cases, requirements, domain driven design, model driven development and modeling in agile projects for IT Works, Hotel Crowne Plaza, Antwerp, Belgium. See www.itworks.be.
  • June 26. Agile anti-patterns. Yes, your agile projects can fail too. Entertaining talk on how to make your agile and Scrum projects fail, at the SDN Event in Hotel Houten, Houten. www.sdn.nl

Delivering products in agile (Smart) projects

In most cases where a form of agile software development is applied, projects are challenged with difficult issues, such as a swaggering scope, unclear and incomplete requirements, unstable software architecture, are quickly approaching dead lines. Within these strict boundaries projects try to deliver high quality software at high productivity – or velocity. This is not an easy challenge.

Delivering just what is needed

Therefore, during agile projects there is high pressure on delivering just that what is needed. The emphasis of an agile project team is on creating just the right (amount of) software, and minimizing the amount of work spent on other products, such as documentation and work in the peripherals of the project. Although many project teams seem to call on this principle to actually not deliver any documentation, the fine art of being agile is delivering just-enough, just-right documentation.

In our experience, a lot of time is spent in agile projects on deciding what’s enough, and moreover, what’s right. Especially when projects are executed in complex organizations, and applying complex (service or cloud oriented) technology, finding the right level of documentation is actually a quite intriguing task, and goes beyond writing (structured or not) user stories.

Delivering products

In the vision of the agile process Smart (and other agile processes, including Scrum and feature driven development) projects should focus on delivering products, not just on performing activities. Please note that working software is not the only product a project delivers.

The agile process Smart suggests to deliver a number of products that will guide projects through these just-enough, just-right in a more standardized fashion. In essence, Smart projects are product driven, as are other agile processes such as Scrum, FDD and OpenUP. During each of the iterations in a Smart project, the team delivers a number of working products. These products fall into a few categories:

  • Project deliverables. In each of the different types of iterations Smart suggests to deliver additional products that will help drive your project to success. These products might include well know deliverables such as a project proposal and non-functional requirements.
    Although none of these product are actually mandatory in a Smart project, they are considered good practice, and over the years have been produced in numerous Smart projects. Using these standard suggested products, organizations get an even better grip on the projects at hand. Note that emphasizing the existence of other project deliverables besides working software (in smart use cases) does not mean projects become less agile.
  • Smart use cases. The body of products delivered in a project is formed by smart use cases, small discrete pieces of functionality that drive development. Smart use cases is a technique to rapidly model your functional requirements at a equal-granular level. Smart use case supply a small and very useful unit of work, and furthermore serve as the main unit of estimation, planning, but also drive realization, testing and even delivery.

All products, both project deliverables and smart use cases run through (a subset of) the product life cycle.

Project deliverables

All products that need to be delivered to run your projects and do not deal with implementing functionality directly (which moreover is partitioned in smart use cases) are referred to as project deliverables. Most of these project deliverables are one-off, although they might be maintained and updated during the project, such as the project’s software architecture and the domain model. Any Smart project needs to decide which of the suggested project deliverables will be produced, and in which iterations.

IMG_0243

An easy way to achieve the optimal set of project deliverables is to add the products suggested by Smart to the project’s backlog during the different iterations defined in the Smart process. Or alternatively, add them to the backlog at the start of the project. This allows project teams to add them to the list of products to deliver in any of the iterations.

For example, during the first Propose iteration the smart use case model, a project estimate and a project proposal can be added to the iteration backlog. At the start of the Scope iteration, the software architecture and reusable services might be added. At the start of each of the iterations, the customer and the project team decide which of these products will be picked up and produced.

Examples of project deliverables

Some examples of project deliverables are:

  • Project proposal. A first proposal covering the primary scope of the project and a first cut estimate is produced as a the final project deliverable for Propose iterations.
  • Project plan. The project plan describes the project approach, the stakeholders and goals, business case, risks, resources, timelines and project estimate. The project plan is mostly delivered at the end of Scope iterations.
  • Iteration plan. For each iteration a very brief iteration plan might be documented, sometimes not longer than a single page. This iteration plan describes the list of products (mostly smart use cases) to be implemented and resources needed. In most projects, iteration plans result from the planning session at the start of each iteration.
  • Software architecture. Document describing the architecture for the project. Ideally, your software architecture is an instance of a reusable reference architecture that might be in place at a organization. Having a reference architecture will allow a project team to focus only on deviations. This saves valuable time and effort.
  • Business process model. Most projects implement one or more business processes, and a number of additional functions that support these processes. Smart use cases can be derived from these business processes, independent of how these processes are modeled. The business process model is either obtained from the organization, or created during the project.
  • Smart use case model. The smart use case model is leading in Smart project. It delivers software estimates, and presents an overview of the scope of the project.
  • Domain model. Most custom software development projects will have a model describing the business domain and business services. Sometimes this model stems from previous version of the software, for instance modeled in a data model. In service oriented projects, the domain model in most cases overlays the services called in different back end systems, as forms the basis for a service consuming front end.

Again, in most cases these deliverables are one-off. They are created once during a project, but quite often maintained or updated later on, think of the domain model and a reusable services model.

Smart use cases

Most of the work in delivering working software in iterations that are of type Realize or ‘Finalize” relates to the realization of smart use cases. The smart use case has become our main unit of work. They are implemented following the product life cycle. The work on each individual smart use case includes analysis, design, test design, build, test and acceptance. This work is always visualized using an agile dashboard, either using post-its on a wall, or using an (online) automated dashboard.

Read more

You will find more information on these subjects at:

Implementing smart use cases. Guest lecture at Hogeschool Arnhem Nijmegen

In the second half of last year, I did a guest lecture at the Hogeschool Arnhem Nijmegen (HAN) in Arnhem on an invitation by lecturer Rody Middelkoop. I’m sorry but I can’t remember the exact date – only that I had an upcoming flue. Although if was a Friday afternoon, the audience was good, about 60-70 lecturers and students.

I also remember I covered a lot of ground, and of course high-paced. Starting at why waterfall is such a wasteful model, and why agile (in general) serves most projects better. Went on to agile key principles, and a short comparison of agile processes, such as Scrum, XP, Smart, DSDM. Then I moved to explaining Smart, and the role of smart use cases in Smart’s agile process. After demonstrating the agile requirements approach in our Accelerated Delivery Platform, I also show how smart estimation (estimation project complexity using an abstract scale, based on smart use cases of course). From that I went on to implementing smart use cases in C#, software architecture, and the design patterns involved, and last but not least, generating code from smart use cases and the domain model using the Tobago MDA tool set.

Originally my talk was planned from 15:00 hours to 17:00 hours. Remember it was a Friday afternoon. However the response was warming, and at 17:30, I was about halfway through the story. I offered to stop and come back later, but the audience insisted that I would complete my story. So I did, and it was about 18:30 hours when I left the building…

Anyway, here’s the slide deck…

Navigating through the hypes, Software architectures and patterns to help avoiding your projects to crash – this year’s DevDays talk.

Good to hear that I’ve made the program of this year’s Microsoft DevDays. Will be a challenging talk on software architecture and patterns, titled just like this blog post. Here’s the description. Hope you like it.

Navigating through the hypes, Software architectures and patterns to help avoiding your projects to crash

When it comes to .Net software development, more and more frameworks enter the market. Both from Microsoft and in open source. Just think of all the very useful frameworks, such as ASP.NET MVC, Castle, WF, Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, WCF, nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF.

Once a project chooses to apply one or more frameworks, trouble begins. What if you require additional features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway your project? What if the author of your favorite open source framework suddenly stops developing? What if the framework contains bugs or omissions? And what if a new version of the framework is released that is implemented totally different? These and many more everyday problems will cause your project to come to a halt, or at least make you perform serious refactoring.

During this highly interactive talk Sander Hoogendoorn, principal technology officer at Capgemini, chief architect of Capgemini’s agile Accelerated Delivery Platform, and member of Microsoft’s Visual Studio Advisory Board, will demonstrate pragmatic software architectures and patterns that will help your projects to stay away from framework problems, and how to keep your code independent of framework choices. In his well known slightly ironic style Sander will present different models of layered architectures, and explain and use bridge patterns, managers, dependency injection, descriptors, and layer super-types.

Of course, the speaker will illustrate these insightful patterns with lots of demo’s and (bad) code examples using blocks from Microsoft’s Enterprise Library, nHibernate, Log4Net, and the Entity Framework. Delegates will benefit from this talk by learning how to improve the structure and quality of their software architecture and code, and how to avoid the pitfalls of applying frameworks to .Net software development.

Client/service architecture. Domain driven development in the distributed era. Episode IV

Go to episode three.
Go to episode two.
Go to episode one.

In case you’re wondering why doesn’t this dude come to his point, you’ve probably missed it. I’ve made it already. The point is: you should always have a single point of truth, and at most have it reproduced on the server side. Which in most cases you don’t control anyway. Centralize your domain or business logic in the domain or business layer. Do not go directly from your front end to the server, but always use the domain layer as an intermediate. The longer I’m in this business, the more I am convinced of this simple, but golden rule.

Client / service architecture

Now you’re probably wondering why I am still blabbering on about this client / server technology. Client / server is dead and long gone isn’t it? Well, it should have been. But it isn’t. A lot of water went under the bridge since 1996, but this two-layered architecture is hard to wash out – in a sense it’s a bit like waterfall or Cobol. It’s still here in our everyday projects, on a day-to-day basis. Even though we are now building applications in service oriented architectures, and have build in a component based model before that, and perhaps in the near future are even building in a cloud model. Let’s call this client/service architecture.

Much to my liking, I get to do a lot of code audits, mostly on .NET applications. Code in these newer styled projects, such as web, service oriented, or even cloud is not that different from our old client/server code. Or if you just witness presentations at conferences on new technologies, or on emerging frameworks, such as ASP.NET MVC or ADO.NET Data Services. Or scroll around the average code example on web sites and blogs. Nothing changes. Developers are still binding their DataSet to their DataGrid. Please check out the following code.

private void ManageCustomer_Load(object sender, System.EventArgs e)
{
   string connString = "server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI";
   string sql = @"select * from customers";

   SqlConnection conn = new SqlConnection(connString);
   SqlDataAdapter da = new SqlDataAdapter(sql, conn);

   DataSet ds = new DataSet();

   da.Fill(ds, "customers");

   grdCustomers.SetDataBinding(ds, "customers");
}

The Hello World excuse

I just picked this code example from an arbitrary web site. It comes from an ASP.NET web page. There’s two options: either this is a Hello World style demo, or it represents the architectural style of the whole application. In the first option, the developer is forgiven. The developer in question will use Hello World as an excuse not to practice good architecture. There’s probably very little time during his demo to explain about good architecture – although I think you should always explain about good architecture, as many developers will just follow the code examples offered and build them into their real-life applications. “But hey, I only wanted to demonstrate this new piece of technology.” Sorry, that’s no excuse.

Hence, the second option: this code example could actually represent the architectural style for a real-life application. In which case you’re screwed. Having a connection string and a SQL statement set up – in strings – on every web page is probably not what you should do. Even though these mistakes will already kill you in maintenance mode, this is not what I wanted to express. Things get worse: this code does not have room for business logic. A DataSet with customers in it is retrieved from the database, and a grid view called grdCustomers is filled with this data. What if I want to run some business logic on my customers? Where do I put it?

The service oriented Hello World excuse

Let’s move on. You might consider that the previous code example is from the old world as it is still centered around the database. Even though it is quite recent code. Let’s consider a real new age code example.

private void GetAccountsData()
 {
     CrmAuthenticationToken token = new CrmAuthenticationToken();
     token.OrganizationName = "MicrosoftCRM";
     token.AuthenticationType = 0;

     CrmService service = new CrmService();
     service.CrmAuthenticationTokenValue = token;
     service.Credentials = System.Net.CredentialCache.DefaultCredentials;
     string result;
     string fetchXml = @"<fetch mapping='logical'>
         <entity    name = 'account'>
         <attribute name = 'name'/>
         <attribute name = 'telephone1'/>
         <attribute name = 'address1_city'/>
         <attribute name = 'address1_country'/>
         <attribute name = 'websiteurl'/>
         <order attribute = 'name' descending='false' />
         </entity></fetch>";

     result = service.Fetch(fetchXml);

     _crmData.ReadXml(new StringReader(result));
 }

This particular code example comes from a SharePoint WebPart. This web part is used to represent a list of accounts and select an account from this list. These account are retrieved not from a database, but from a service in Microsoft CRM. The accounts retrieved are stored in an instance variable called _crmData. Unfortunately, this variable is not a collection of Account objects, but rather is defined as a DataSet.

DataSet  _crmData       = new DataSet();

And to complete this service oriented example, the instance variable _crmData is then used to render the web part by binding the GridView to the first table in the DataSet.

protected override void OnPreRender(EventArgs e)
 {
     grdCrmAccounts.DataSource = _crmData.Tables[1];
     grdCrmAccounts.DataBind();

     lblHeader.Text = "Accounts from Microsoft CRM";
     lblHeader.ID = "header";
     base.OnPreRender(e);
 }

All in all, again this is a typical Hello World demo scenario that was presented to illustrate the combination of SharePoint and Microsoft CRM. But again, this kind of code will also appear in real-life applications without any doubt. It’s easy to see what’s missing here. There is no location to put our possible business logic.

In a service oriented scenario this means  we totally rely on the definition and signature of the objects from the server, in this particular example on the definition of the Account object in Microsoft CRM. Although relying on services sound reliable, it is in fact no more reliable then to trust on the definition of a table called Accounts in an underlying database. Hence the phrase client/service architecture.

Pragmatic model driven development in Java with smart use cases and domain driven design

In our Accelerated Delivery Platform we generate code from our standardized smart use cases and the domain model, using our Tobago MDA tooling. See www.accelerateddeliveryplatform.com for more details.

In our daily practice we generate for a variety of architectures in the .Net space. For instance, we apply our own frameworks, or combine these with open source frameworks such as nHibernate, and blocks from Microsoft.

image

Until recently, we did not have templates to generate Java. However, Rody Middelkoop from Avisi in Arnhem. He created a set of templates to also facilitate that, resulting in the generation of large parts of Java applications. Rody and I decided to send in a proposal for the upcoming J-Spring Conference. Here it is:

Model driven development has a promise of high productivity. However, many approaches fail to deliver. Sander Hoogendoorn (Capgemini) and Rody Middelkoop (Avisi) will present a very pragmatic approach to model driven development, based on modeling smart use cases and domain models in UML. The speakers elaborate enthusiastically on this approach and the techniques used, and they will model and generate a fully deployable Java applications live on stage!

In this unstable economy, organizations target software development at shorter time-to-market and high productivity. Model driven development has a promise of raising productivity in projects. However, many approach fail to deliver this promise. During this high-paced, interactive talk speakers Sander Hoogendoorn (Principal Technology Officer and agile thought leader at Capgemini) and Rody Middelkoop (Technical evangelist at Avisi, and lecturer at the Hogeschool Arnhem Nijmegen) share their very pragmatic approach to delivering software using model driven development. First, Sander will elaborate on the modeling and code generation approach, that relies on smart use cases and smart use case stereotype, a solid software architecture and domain driven design. Next, Rody will take the stage and demonstrate how this approach effects building Java web applications, generating a fully deployable Java EAR live on stage! Although other architectures and frameworks can be applied, Rody will use open source Java frameworks such as Ant, FreeMarker, Struts2, Spring and JPA/Hibernate3.

Reblog this post [with Zemanta]

Single point of truth. Domain driven development in the distributed era. Episode III

Go to episode two
Go to episode one

Client / server could have been a much more successful era in software development, if it wasn’t for this copy-and-paste programming, leading to applications that slowly became unmanageable. I have seen this anti-pattern occur in any of the popular client / server technologies. Without exception, whether it was Visual Basic, PowerBuilder or SQL:Windows and even the older web technologies, such as ASP and even early Java applications.

Splashed business logic

We still bare the fruit from the client / server era. Many of the projects we currently undertake are application migration projects, or re-engineering projects. Although tools exist that claim to do fully automated migration of client / server apps, I find that hard to believe. Having done many code reviews on these poorly constructed applications, these all seem to have one thing in common: the business logic is splashed all over the place, and hardly ever consistent.

Single point of truth

And the nasty thing is: we could have prevented most of this problem, if we would have known then what is now much more common, although less widespread as it should be. But I’ll come back to this in later episodes.

We should have introduced a single point of truth in our client / server applications. We should have constructed a domain layer – or business layer – that contains our business rules and validations, as in the figure below. Separating concerns is a popular catch phrase. In this case separating the presentation logic of the user interface from the domain logic in the domain layer.

image

Now we only have one location of our simple business rule. For now, I’ll leave it in the middle where in the domain the business rule sits. There are a few options. If the customer changes his mind in this situation not much harm is done. We simply modify the one business rule in the domain layer and we’re back on the road. All presentation logic simply refers to this location, so we’re good.

For as long as they both shall live

Of course, this refactoring comes with a couple of consequences. For starters, you could reason about the fact whether a copy of the business logic should also be present in the database underneath. There are a couple of thoughts to consider here:

  • How and by whom is the is the database approach. If our application is the only party to talk to the database, and if this situation remains in tact, you’re quite safe, and you could consider not implementing the rules in the database.
  • If you’re not sure who else approaches the database, you will need to implement the rules at least in the database too, otherwise there is no way of guaranteeing continuity and consistency.
  • If you decide to have the business rules implemented double, make absolutely sure that the two versions of the truth are in sync, and will remain in sync for as long as they both shall live.

This taking into consideration, applications and database should have been much easier to extend and to maintain. Of course, back in the nineties of the previous  century, more and more people started to realize this. That’s when multi-layered architectures became in fashion, which they still are.

The merits of two-tier architecture. Domain driven development in the distributed era. Episode II

Go to episode one.

So now you’re stuck with this two-tier architecture. Is this a problem. Well, not yet. However, it can become a huge problem, and it has become a huge problem in many, many client / server applications, in a vide variety of technologies, including several types of (legacy) web application technologies.

The truth is out there

The problem with this architecture again is fairly simple. There is no single point of truth. Business logic is scattered. Consider this simple piece of business logic below.

if (StartDate < EndDate)
{
   ...
}

This code is now in the database, to keep the database from getting harmed. But it is also copied into one of the forms in the application, preferably on an event that is fired when the user tabs out of the field StartDate from, let’s say a Contract.

Eventually, there will be someone on the team of developers who is going to build another form that involves manipulating a Contract. It could be yourself, or any of the other well-educated developers, but there’s always someone how will copy-and-paste the business logic from the other form to the new one. And from that time on the truth is out there. Somewhere. After a while, you will end up with an application that looks like this.

image

And you might not even see that, because it happens over time. For instance, much of this copy-and-paste activity will take place after the application is deployed and it enters maintenance mode. Especially when the boys and girls doing the maintenance were not on the team that built the software.

Customers changing their minds

Still, this doesn’t have to be bad. It will become bad when something peculiar happens: the customer changes his mind on the business rule. Now, I know, that never happens on your projects, but on mine it did and it does. On average, requirements will change about 20% to 25% during the project. And there you go. Let’s say the customer just thought of the fact that the previous rule must be altered. Just a very small change, isn’t

if (StartDate <= EndDate)
{
...
}

So the boys and girls in the development or maintenance team start looking for the locations this business rule applies to. Of course, there is hardly any documentation, so they start searching the code. And you know what, they will find occurrences of the business rule and fix them. But, that’s Murphy for you, they will likely not find all the occurrences. The applications will now look like this.

image

And that’s where client / server fails. Miserably.

Back in the days of client/server. Domain driven development in the distributed era. Episode I

At this point in time, where we slowly shift from service orientation to cloud computing, building business software is more complicated then it has ever been. There are many platform that your software needs to target, and there are even more ways of writing the software.

Beyond choosing technology

Choosing a technology goes way beyond stating that you are doing Java, .Net or Adobe, and can be quite complicated. A vast amount of architectures, patterns, frameworks – open source and vendor specific – is available to make life easier, but choosing more complex. With this paper – in episodes – I will try to make a point for building software around its domain, also in applications that consume services in a distributed environment. Especially in such a service oriented environment, since there is a wide variety of sources your domain can be fed from, including database, ERP, web services and the cloud – where ever that leads us to. In the sequential episodes of this paper, I aim at presenting a collection of patterns that will help you leverage your domain driven design independent of the back ends this domain needs to interact with.

Back in the good old days

But first things first. Back in the old days of client/server life was fairly simple. You could find the a way to get the data you needed from the database, usually using ODBC, and splash that data to a form, usually a Windows form. You could build applications in a jiffy. Didn’t we all love PowerBuilder, SQL:Windows and Visual Basic?

Then life got a little more complicated at the time the customer wanted some validation in the application. Let’s say hew wanted to make sure that the end date of a contract was either blank or later in time than the starting date. Here’s where the discussion started. The developers that previously worked with Clipper or DBase would insist to put this validation in the database. And they did. Nice and safe. The younger developers, including me, however would mention that if validation was delayed until the data reached the database, it was fairly late. Couldn’t we just build the validation into the form? Well, yes we could. And we did. So we ended up with a simple architecture, as shown below.

Client / server softwar architecture

The nasty thing about this architecture is that both arguments hold. Yes, validations in the database is fairly safe. And yes, validating until the data is in the database is fairly late. So now we keep two versions of our little validation rule. One in the database, and one in our form. It’s the same rule. For now.

Application migration using smart use cases and a model driven development approach

Application migration is the process of migrating older applications (often referred to as legacy) to application that have more of less similar functionality, but are developed in newer technology. Application migration has proven to be a crucial but very hard part of software development over the years. Key to such projects is:

  • Automated migration is hardly ever possible. It is hard for tools to migrate towards new development models, such as from Windows to web, because underlying different platforms have totally different programming models.
  • Business logic is scattered. In most legacy applications, the business logic is scattered all over the place, from user interface to the database. New architectures and platforms often serve best when applying domain driven design and development to centralize such logic. Migrating business logic is often hard.
  • Process logic is in the user interface‘. While current platforms and architectures offer to build software around business processes, this wasn’t always the case. Previously, lots of software was built around maintaining the database. Process logic is therefore either not present, or entwined in the user interface, which makes it hard to unlock.
    Using our Accelerated Delivery Platform (ADP) we have done some successful application migration projects. The ADP holds a number of accelerators that contribute in lowering your workload in such projects to a great extend.For instance, we model requirements using smart use cases and domain models. Smart use cases are an excellent unit of work to estimate, plan, and reuse functionality. See the example model below. Moreover, we generate a lot of code from both models using our generator Tobago MDA, but instead you might use other code generators, such as Velocity or CodeSmith.
    Task
    This code runs under (our) proven .Net frameworks. But, smart use cases also serve as a great unit of requirements when remodeling existing applications.

Strategy for application migration

Using these accelerators a clear strategy for solving re-engineering assignments such as yours is defined as follows:

  • Re-model in smart use cases. Examine the existing applications and model smart use cases from that.
  • Model the domain. Create a model the domain, for instance from existing data models.
  • Generate the new application. Generate the larger part of the new application using our model driven approach and Tobago MDA.
  • Examine business logic. Examine the old code for business logic and extend the generated application with this logic (in the domain layer).
  • Round up user interface. Finish of the newly generated user interface by examining the old user interface.

Of course, this approach does not solve all of your problems, and still leaves manual work discovering the business and user interface logic. But this approach reduces a lot of work. Even better, since the new application was modeled and generated, it is possible to migrate the model to several different platforms, such as mobile and web, or to migrate to a new platform much more easily in the future.

We have applied the accelerators in this platform in many projects and at many customers. Currently we support generating both Windows applications and ASP.NET web applications, and we have started to support Silverlight front ends and (even) Java applications.

Generated code is plain C# (or VB.NET or Java) and can be read and extended at any time. As the platform is shared with our customers in a open source-like manner, all accelerators in our platform come free of cost (also for our customers). There are 8 different training courses available to come up to speed with the platform.

This presentation will explain this approach to application migration into more detail.

So much to write, so little time

It’s too bad there’s only 24 hours in a day. There are so many ideas in my head that I still have to write down, that I have to make a (short) list now to keep my head from exploding.

So here it is:

  • White paper on how to do agile SAP projects using smart use cases.
  • Article on applying smart use cases in BI project (started).
  • White paper on agile accounting models (80% done).
  • White paper on my agile methodology Smart.
  • Book on agile / Smart in everyday practice (lay-out done). Have to find publisher.
  • Book on software architecture and patterns for .Net projects (started). Need to find publisher.
  • White paper on pragmatic model driven development.
  • Wiki page on how to use Tobago MDA.
  • Article on pragmatic model driven development in Java (with Rody).
  • Article on Descriptor pattern
  • Article on Smart Reference pattern (80% done).
  • Blog on agile mediocrity.
  • Article on application migration using smart use cases and the Accelerated Delivery Platform (started).
  • Ugly blog on the hype of cloud computing, following and extending the hypes around service orientation and component based development.
  • White paper on distributed agile software development.
  • Book on project anti-patterns (lay-out done).
  • White paper on our three references architectures, identifying all types in the layers, and their responsibilities.
  • Update the wiki with Smart 3.0 (30% done).
  • White paper on level of ceremony in agile methodologies (30% done)
  • Wiki page on mixing Scrum and Smart.
  • Wiki page on splitting smart use cases to work items.
  • Wiki page / article on testing smart use cases (80% done).
  • Newsletter item on visit of .NET PAC in Redmond.
  • Book on smart use cases.

And moreover (added February 6):

  • White paper on agile for software product development.
  • White paper about implementing agile smart.
  • Blog on questions raised during recent discussion on implementing agile at a large international bank.
  • Blog post(s) on going from Twitter API to service oriented software.

So help! Any votes or assistance offered?

For more information around these subjects see: www.accelerateddeliveryplatform.com

Talk at Javapolis 2007. Popular project anti-patterns

This is the video from Parlays.com that presents the talk I gave at the last JavaPolis conference in Antwerp, Belgium. During the talk I ask myself the question how everybody in their own role can attribute to making our project fail, as it is far too complicated to make your projects succeed.

The talk presents popular anti-patterns I’ve gathered over the years, such as Titanic Projects, the Bob-the-Builder Syndrome, PowerPoint Architecture. Enjoy.

Why do you need a layered architecture?

The first business software I wrote professionally – that is, got paid for – was a set of small and similar calculation applications. I wrote these in the pre-Windows era in some version of Turbo Pascal. And no matter how ignorant I still was about good software architecture, these small applications already had a notion of layered architecture. And though the term design pattern wasn’t even coined back then, many people consider layered architecture to be one of them. Personally I think that writing software in a layered architecture is more of a way of life. I wouldn’t know any other way to build business software. Would you?

Why are layered architectures so useful? Well, first and most of all they allow you to distinguish and distribute the responsibilities that your application, your code has to deliver value to the end user. That is, the user interface does not contain components or elements that handle business logic. Business logic resides in a separate layer. A data access layer does not have anything to do with presenting the data, it deals with the database.

Layered (food) architecture

And if your thinking this is trivial, please note that there are hordes of developers who still write database connection strings and queries in each web page they develop and who still validate the same business rules in each web page they data is presented. You’re not alone.

Distinguishing and distributing responsibilities – if done correctly and pragmatically – will deliver a number of benefits to your projects:

  • Easier to understand. Code will be easier to understand, not only for the developers who wrote it, but also for the poor bastards who have to maintain the code once delivered. Code is just easier to maintain when you know where to find it. Code becomes traceable.
  • Easier to write. Have developed applications for over twenty years, I think I’m entitled to say that a day’s work is more fun writing software under architecture. It’s cleaner, more serene.
  • Easier to test. Although I personally consider testing software not the most fun, I do think that software that is written under architecture is far more modular. This makes it possible to define independent unit much better, which makes unit testing easier and better. In fact, testability is one of the main motives to define your layered architecture. Design it with testing in mind.
  • Easier to extend. Last but not least, having a layered architecture in place will allow you to add new features, or change the current features more easily. Adding a new use case to the system, or extend the business rules on a particular domain object much harder if the process or business logic is spread throughout the code.

Need I say more?

Why do we need software architecture?

Over the past twenty or so years I have been involved in many software development projects, code reviews, and software factory implementations. Although I had stretched the virtues of good software architecture for decades, it wasn’t until a series of recent event, that I really started re-valuing of having a sound software architecture in place. And to me a well-defined software architecture merely describes the patterns used, the layers applied, the types of classes in these layers, and how they collaborate. Primary goal would be to create structure and a clear separation of concerns in your application code.

Code is like ivy

In October and November, I was running a code audit on a 1.4 million lines of code ASP.NET web application, the second large audit I did in a short period of time. Both products where web applications that were targeted at big audiences, and that were meant to last for a long time. And in both cases the software architecture was set up really bad. In one example, I couldn’t even discover a decent software architecture through the code. In just three years this application had grown from a small web application to an enterprise web portal, and a few dozen developers, partly external from the company, had written code in a wide variety of styles. With no architecture in place, the code grew like ivy on a moisty garden shed, resulting in poor maintainability and low productivity in adding new features to the product.

Midst November, I found myself in Barcelona, visiting the Microsoft TechEd conference, where a number of new frameworks were presented – although most of them still in beta. Some of these framework already made their way into full swing projects, one the largest run for one of our Belgian customers. Looking at the presentations, and talking to developers, it occurred to me that a lot of people have their software architecture dictated by the frameworks they apply.

Just think of this. One of the developers I talked claimed to have a good software architecture just because he was using the ASP.NET MVC framework. My vision however is different. It should simply be the other way round. You have a sound software architecture in place, that expresses the business needs and the technical concepts to implement these business needs. Then if you’re interested in applying a particular new framework, you should only need to map the concepts of that framework, say ASP.NET MVC or the Entity Framework, to the concepts in your software architecture. And if it fits, use it. And if it doesn’t either don’t use it, or encapsulate it, so that it will fit in.

Benefits of a sound software architecture

So concluding, if your organization has a software architecture in place, this will offer some rather relevant benefits, which include:

  • Higher productivity. It is easier to add new features to existing software, since the structure is already in place, and the location for every new piece of code is known beforehand.
  • Better code maintainability. It is easier to maintain existing software, as the structure of the code is visible and known, so it’s easier to find bugs and anomalies.
  • Higher adaptability. New technical features, such a different front ends, or adding a business rule engine are easier to achieve, as your software architecture creates a clear separation of concerns.
  • Hype agnostic. Last but not least, it will allow you to see hypes and fads in the industry – or which there are a lot – in the light of your current structure, and to fit these hypes and fads in if so required.

So?

So why is it so many organizations and project to not adhere to having such a software architecture in place? It’s beneficial and it doesn’t require a big up front state of art research & development. Just common sense and best practices.

Implementing value objects

When reasoning about business domains in projects with customers, domain objects and their services are always discussed. But if you listen more closely you might hear additional requirements on the domain. “Off course, customers can also find a book by typing in their ISBN” or “we also register the customer’s web site, by adding the URL.”

When to use value objects?

Both ISBN and URL have meaning to the customer’s domain. As most of us are aware, both types are stronger than just a character array in the database. This is when value objects become useful. A value object is a small and simple object, such as Isbn or Email that is meaningful to the customer domain, and is used for validation, often as type of properties of domain objects.

Value objects

During a recent training I presented in Amsterdam (on UML), a software architect from the Dutch tax and customs administration (DTCA) explained that they hardly ever use base types such as int, string or even DateTime, but declare value objects for just about everything. His argument was that we know more about almost all domain object properties than that they’re just a string or a number.

Recipe for implementing value objects

My straightforward recipe for implementing a value object:

  • Identify value object. Identify the value object you need, which is in most cases derived from the domain model. Give the new value object a proper name, such as Email, Password, or SubscriptionNumber.
  • Represent value. Think of how the internal value for your value object can best be represented. In most cases a string will do just fine, otherwise DateTime is also a frequently used representation.
  • Implement validations. Program the validations and checks required to validate whether a value presented is actually valid.


private static Regex Expression =
new Regex(@”^(?=.{13}$)\d{1,5}([-])\d{1,7}\1\d{1,6}\1(\d|X)$”);

public static bool IsValidIsbn(string newvalue)
{
return Expression.IsMatch(newvalue);
}

public Isbn(string newvalue)
{
value = null;

if (string.IsNullOrEmpty(newvalue)) return;

if (!IsValidIsbn(newvalue))
{
throw new FormatException(String.Format(“{0} is no ISBN”, newvalue));
}

value = newvalue;
}

  • Consider null values. Consider if a null or an empty value should be allowed for your value object.
  • Implement interfaces. Implement the proper interfaces for your value object, such as IComparable, and the generic interfaces IComparable to compare instances of your value object and IEquatable to see whether two instances are equal.
  • Implement accessors. Implement any additional accessor methods your type requires, including the TryParse() pattern, but make sure your value object is immutable.
  • Decide type. Consider whether your new type should be a value type or a reference type. This is largely depending on the size of the internal representation.

Benefits of value objects

There are validations to be met. Not all strings represent a valid ISBN or a valid URL. Although these well known examples are easily identified, quite often there are more hidden features of this kind that you might not notice at first glance, if you are not an expert in the specific business domain. Think of an employee number each new employee is associated with, or specific types of passwords.

Read more on implementing value objects

Last year I wrote a more elaborate article on implementing value objects. It was published in the Australian magazine Inernational Developer Magazine. Don’t hesitate to download the PDF at: Implementing value objects (PDF).

Increasing the productivity of software development

Earlier this week I presented a talk at the inspiring Software Developers Conference 2008 in Noordwijkerhout, the Netherlands. My talk had an inspiring, or at least intriguing title: How to keep our jobs. Why? Well, let me share some thoughts on the productivity of software development projects.

A 100-fold

Recent research by Gartner shows that the productivity of software development will need to increase by a 100-fold. According to Gartner, there are 2 very simple and straightforward reasons for this:

  • Not enough newbies. The number of university graduates, and other people starting new with software development is too limited.
  • Increasing demand. The demand for new software is ever increasing, for instance becomes of emerging technologies and platforms (think of mobile and web 2.0).

And from my personal experience I would add:

  • Poor quality software. I perform a lot of code audits on applications, often quite large – say of over 1.000.000 lines of code. Even with such large applications, built by respectable companies, the quality is often brain damaging poor, frequently due to failing or total lack of software architecture. Such software is therefore very hard to maintain or extend with new features.
  • Ongoing business. There is a vast amount of software present in the marketplace that will need to be maintained for a very long time. Large transactional systems with banks (nationalized or not), governmental organizations or packaged software such as SAP and PeopleSoft. Although not mind-blowing, this work still needs to be done, and limits the amount of resources available for new development.
  • No silver bullet. There is no single methodology, technology or company that is able to provide the productivity to meet up the Gartner challenge, no matter how hard vendors will try to convince you that their new tool or framework will get you there.
  • Complexity of technology. Technology is ever more increasing in complexity. As much as you might suggest that tools and technologies have evolved over the past 20 years – about as long as I have been in this business – we do not reach higher productivity in projects than we did back then during the client-server era. In good old PowerBuilder projects we reached productivities of around 2.5 hours per function point. Nowadays, when applying our full blown agile Accelerated Delivery Platform we can about get to the same level, as was recently calculated by a respectable customer. And this is 20 years later. Another quick example? Take service oriented architecture. Often presented by vendors and architects as an approach where you just model the business processes and out comes your new software. Yeah right. Building service oriented software is still hard and technologically complex work. And no matter who gave you the idea that service orientation will help you get rid of object orientation, don’t believe it. You will need good old object technology to build all this stuff architects come up with: user interfaces, process logic, business logic, interfaces to middleware. It’s just not that simple.
  • Band wagons. We developers tend to go along with every new tool, framework or language extension that comes of the Microsoft, Sun, IBM, Oracle or open source band wagons and base our software architectures on these new, unproven technologies. This results in much time being spend on solving technology issues, rather than customer issues. And I should know, I have been (re)building frameworks over the past 20 years.
  • Snail speed projects. Projects are often executed at snail speed, and have enormous amounts of slack – time wasted by people just waiting for other people to finish their work or waiting on decisions not being made. My worst case? I once spent 4 months lingering in a project that was on hold until a board high up in the organization – indeed, a large international bank – approved on the new budget. And I wasn’t the only one – there were 60 of us.

The sun always shines

As said, there is no technique or technology that will lift our productivity a 100-fold. No sir. Moreover, there is not even a combination of technologies that will do so, no matter how much vendors would like you to believe that they’ve just invented the silver bullet. We’re just not there yet. But we could try. There are promising technologies, tools and methodologies. There always have been. Some ideas will help us get underway slowly and steadily (alas):

  • Become agile. Letting go of large process and waterfall styled methodologies will produce better software a higher velocities. Agile software development is more cooperative, responsive to changes, and removes much of the air from waterfall styled projects. Not only in small, but also in very large and even distributed projects. After having evangelized agile software development for the past 10 years, I know see agile finally moving into the mainstream.
  • Become communicative. Do not design and write your software under water, and submerge after months. Keep in touch with your customer during the whole project. Preferably execute (at least a large part) of your project at the customers’. Let him or her be in the lead. Shorten your feedback cycles to a daily, if not hourly basis.
  • Become standardized. Why does every new project define its own software architecture? And why are a large number of these new architectures so poorly designed? Why do we developers go along with every new (and often unfinished) technology fad? Standardization on good, sound architecture (domain driven of course) will help create better quality software that is easier to maintain and extend in the future. But be pragmatic, travel light. Even better, standardized software architectures allow for advanced, productivity increasing techniques, such as model driven software development and further down the road domain specific languages.

Again, none of these ideas are the silver bullet to solve all our problems. And the current financial crisis doesn’t help either. But, enough said. I’m not into pessimistic locking. We geeks have the best jobs in the world. The sun always shines from our asses. Just think of it. What other job will just let us write code all day?

Sander Hoogendoorn at the DevDays 2008

Finally, after some experimenting we’ve got it. My team managed to put out the broadcast of my talk on everything and the kitchen sink on YouTube, and moreover, link from that. See the results here.

Introduction

The introduction part with some jokes in it.

Software architecture, design patterns and smart use cases in code

A brief introduction into software architecture now and in the old days.

The remaining parts can be viewed on YouTube. Check out:

http://www.youtube.com/user/smartusecases

Talk on DevDays 2008 combining smart use cases, model driven development, software architecture, Silverlight and WCF

At the last Microsoft DevDays Conference (2008) in Amsterdam I did a talk (sorry, it’s in Dutch) that covered a lot of subjects, including software architecture, agile software development, dependency injection, domain modeling, smart use cases, Silverlight, WCF, model driven development, Tobago MDA, our Accelerated Delivery Platform and a lot of other stuff that I can’t remember (getting old).

In the meantime I try to build (live) a couple of applications, that is model, generate and finish the code. During the talk I’ve created a server side application that provide web services, an ASP.NET front end, and a Silverlight front end. Pff. And all that in merely an hour.. As you might expect, my pace was rather high.

Well, without further ado, here’s the video Microsoft shot of my talk. Enjoy.

http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=932

Core [in Dutch]

Het is maandagmorgen. Er schijnt een waterig zonnetje over Ede. Ik parkeer mijn auto op het parkeerterrein van de Reehorst dat verlaten oogt bij de start van de nieuwe werkweek. Ook vandaag is de Reehorst het toneel voor een Software Developers Event. Één sessie in het bijzonder heeft mijn interesse: Addressing non-functional requirements with aspects.

Waarom nu juist deze sessie? Het verhaal gaat over PostSharp, een aspect oriented framework, en wordt gegeven door Gael Fraiteur, de bedenker van het framework. PostSharp is geschreven in C# en is een hele cleane, voor reguliere developers begrijpbare implementatie van aspectoriëntatie. Nadat in mei op een conferentie in Zurich al een presentatie over PostSharp had bijgewoond, schreef ik op een terras meteen al mijn eerste aspect. Heerlijk eenvoudig!

Frameworks. Ik kan er niets aan doen. Ik hou gewoon van frameworks. Heerlijk om te zien hoe developers, teams en project hun generieke problemen oplossen. Of eigenlijk, zoals ze keer op keer dezelfde problemen oplossen. Want wie maakt bijvoorbeeld het id aan van een nieuw domeinobject? De applicatie of de database?

Trechter

Soms levert het kijken naar code uiterst aangename middagen op, zoals bij een recente code audit die ik samen met een collega uitvoerde op een enterprise portal voor een wereldwijd bekend merk. Laat ik het anoniem houden. Een schoolvoorbeeld hoe het niet moet. Meer dan een miljoen regels code. De ontwikkelaars hadden getracht een servicegeorïenteerde software architectuur te implementeren. Waarschijnlijk op aanraden van de architectuurafdeling van het bedrijf. “Wij ontwikkelen hier altijd onder architectuur. Een service georïenteerde uiteraard.” In deze portal betekende dat alle bedrijfsfuncties vanuit de webpagina’s als web service werden aangeroepen. Op zich nog niet verkeerd, al gaf het deployment model in te uitgebreide documentatie geen aanwijzingen voor de noodzaak hiervan. Bijzonder fraai was dat al deze services – 354 in totaal – allemaal op een en dezelfde klasse waren geschreven. Met recht een trechter.

Vorige week verzorgde ik in Antwerpen een tweedaagse training in het pragmatisch toepassen van UML. Ik kom graag in Antwerpen. Fijne terrassen, prima bier. En zo belandde ik aan het eind van een hectische eerste cursusdag op een terras op de Melkmarkt met twee cursisten.


Cafe Pelikaan op de Melkmarkt in Antwerpen

Beiden werken voor een klein bedrijf in Utrecht dat software ontwikkelt voor zorginstellingen en ziekenhuizen. Deze software, zo verhalen de twee functioneel ontwerpers, wordt ontwikkeld in PHP. Ooit gestart door twee techneuten met een goed idee voor een onontgonnen markt en voldoende kennis van PHP is het bedrijf nu vijftig man groot. Maar bij de start gebeurt het! Je schrijft je eerste code en ontdekt dat sommige software herbruikbaar kan zijn. “Hé, we hebben een object Patient en een object Operatiekamer en die worden beide opgeslagen. Laten we dat isoleren.” En voor je het weet ontwikkel je je eigen framework. Met alle bijzondere principes en eigenaardigheden vandien.

Jaloers

Het ontwikkelen van frameworks vergt een heel eigen vocabulaire, patterns en best practices. Al eens naar het patroon layer supertype gekeken? Ook model-view-controllers zijn er in overvloed. En gebruikt niet ieder project een object relational mapper? En of dat nu Microsoft’s Entity Framework , Hibernate of wellicht een eigen implementatie is? Alles is mogelijk! En wellicht maken uw projecten gebruiken maken van dependency injection – het mechanisme waarmee pas op runtime afhankelijkheden worden gelegd. Gebruikt u ObjectBuilder of zijn opvolger Unity? Of dan toch liever open source? Probeer Windsor. Ook bij Microsoft lusten ze wel pap van het schrijven van frameworks. Microsoft – of meer specifiek Scott Guthrie – heeft zich onlangs alweer van zijn beste kant getoond. De beta van Silverlight is de deur nog niet uit, of Scott verlustigt zich al aan zijn volgende framework, getiteld ASP.NET MVC.

Soms ben ik daar stiekum jaloers op. Op de ontwikkelaars van het framework in PHP in Utrecht die daar een op ziekenhuizen gerichte eigen variant van Outlook mee ontwikkelen, als op Gael Fraiteur met zijn PostSharp, maar ook op Scott Guthrie en de andere bedenkers van frameworks bij Microsoft.

Catchy

Er is namelijk niets leukers dan het schrijven van een nieuw framework. Gewoon van scratch af aan. Verzin een catchy naam. Django of Zend. Start met een nieuwe solution in Visual Studio en maak je eerste items aan. Zou ik nu starten, dan zou ik eerst een assembly Core en een assembly Domain aanmaken. En dan een interface IDomainObject definiëren en een klasse DomainObject, die deze implementeert. Met een property Id schat ik in – een value object uiteraard – en een property Title, zoals ook het NakedObjects framework doet voor het eenvoudig representeren van domeinobjecten. En voor de zekerheid overschrijf ik ToString() zodat deze dan mooi Title retourneert. Misschien begin ik vanavond nog wel!

Maar ook voor frameworks geldt: er is een tijd van komen en een tijd van gaan. Op een gegeven moment is de rek uit je framework. De ooit briljante ideëen zijn ingehaald door nieuwere frameworks, die hipper zijn, open source, en uitgebreid gedocumenteerd. Wat te doen? Een complexe keuze. Ontwikkel ik verder aan mijn eigen framework? Implementeer ik daarbij nieuwe features die andere frameworks al kennen? Hoeveel aanpassingen moet ik daar voor maken? Of ontwikkel ik een nieuw framework, dat al deze nieuwe features al standaard in zich heeft, en natuurlijk beter is dan wat de markt nu te bieden heeft. Of stop ik helemaal met het opzettten van frameworks, en ga ik alleen gebruik maken van frameworks van anderen? Of stoten we meteen maar al het ontwikkelwerk af naar India?

Laat ik me er voorlopig maar niet over buigen. Een tijd van gaan? Inderdaad. Tijd om Word af te sluiten en Visual Studio te openen.

Published in SDN Magazine, July 2008.

God Class

In Dutch. Appears in SDN Magazine, February 2008.

Ik weet het nog goed, hoewel het twee jaar geleden was en mijn geheugen niet meer alles is. Mijn collega Wouter belde. Geschrokken. “Zoiets heb ik nog nooit gezien,” begint Wouter, mij nieuwsgierig makend. “Ik dacht dat we in Nederland toch wel aardig konden programmeren. Maar wat ik hier nu bij mijn klant meemaak is ongehoord. Ik heb hier een class voor me met meer dan 3.000 regels code.” Mijn nieuwsgierigheid is gewekt.

Meer dan 3.000 regels code in een enkele klasse is ongehoord. Een typisch voorbeeld van een God Class. Een bekend anti-pattern. Kort samengevat zegt het bijna 10 jaar oude boek AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis: “The God Class is found in designs where one class monopolizes the processing … The key problem here is that the majority of the responsibilities are allocated to a single class.” En inderdaad, Wouter’s klasse is een web part in een Sharepoint-applicatie die alles zelf regelt. De klasse stelt de te tonen controls vast, navigeert door de applicatie, voert validaties uit, maakt verbinding met de database, stelt queries samen en voert deze uit.

Nooit gedacht dat het nog erger kon. Totdat ik eerder deze week door een goede vriend werd gevraagd of ik hem even kan helpen met de deployment van een kleine webapplicatie. Natuurlijk wil ik dat wel. Eerst ruimen we de bekende problemen uit de weg. Zo is de database op zijn laptop ingesteld op Windows-authenticatie en de applicatie niet. En ook heeft de ASP.NET user onvoldoende rechten omdat eerst het .Net Framework was geïnstalleerd, en daarna pas IIS. Ook een bekende.

Op dat moment besluit ik de code eens te bekijken van de webpagina’s van de applicatie. Ik open de code behind page van de hoofdpagina zelfs . Dat had ik beter niet kunnen doen. Er rollen 4.912 regels Visual Basic .Net voorbij aan mijn ogen. Afschuwelijk. En dan heb ik het nog niet eens over die 4.912 regels. De eerste code in het nieuwe jaar, en dan dit. Een valse start. Ik haal er een paar hoogtepunten voor u uit.

If = true
Een makkelijke om er in te komen. Deze constructie mag natuurlijk niet ontbreken.

If Page.Session("ShowRemoved") = "1" Then
   ShowRemoved.Checked = True
Else
   ShowRemoved.Checked = False
End If

Hoewel deze code in principe niet fout is, doet deze mij toch meestal de wenkbrauwen fronsen. Waarom? Het is een symptoom – a smell of bad code – dat je overigens maar al te vaak tegenkomt. Dit kan ook in een enkele regel code.

Constant
En dan heb ik het nog niet eens over het feit dat vergelijken met een string "1" toch wat risicovol is. Was het nou "1", toch "True", of wel misschien "true"? Een eenvodige constante introduceren zou al een verbetering zijn. Laat staan het ophalen van de variabele Page.Session("ShowRemoved"). Zou er bijvoorbeeld verschil zijn met Page.Session("ShowRemoved") of met Session("ShowRemoved"), wat ik verderop in de code tegenkom?

Overal en nergens wordt trouwens gevalideerd aan variabelen die in de sessie worden opgeslagen. En op talrijke plekken worden ze ook van een waarde voorzien. Het zijn globale variabelen geworden. Zo is onmogelijk te garanderen dat bij het uitgevoeren van een stuk code de waarden in de sessie correct zijn. Een van de fraaiste voorbeelden hiervan is het opbouwen van queries zoals hieronder.

strQuery = ""
strQuery = strQuery + "WHERE" + vbCrLf
strQuery = strQuery + IIf(Page.Session("Screen") = "Info",
   " S. Info = 1", "").ToString + IIf(Page.Session("Screen")
   = "Report", " S.ReportScreen = 1", "").ToString + vbCrLf

Prachtig. Prachtig. Ik kan het niet anders zeggen. Waarom worden variabelen als Page.Session("Screen") niet gewoon als argument meegegeven aan de methode waarin de query wordt opgebouwd? Nog een klein voorbeeldje dan maar?

If myValues(1) = "Question" Then
   myQuestionID = CType(myValues(3), Integer)
   …
End If

Zo foutgevoelig. Één typefout en je bent de sigaar.

92
Dat brengt me op de meer hinderlijke eigenschappen van deze code behind. Kort door de bocht: de pagina doet alles. Er wordt een treeview opgebouwd. Er worden heel veel queries (hand)geschreven en uitgevoerd. Het zijn er 92 om precies te zijn. De code behind telt overigens 115 methoden.

Is dat nu zo erg? Denk eens aan onderhoudbaarheid. Veronderstel dat er een kleine wijziging komt in het domeinmodel van de applicatie. En veldje erbij, een veldje er af, misschien een nieuw domeinobjectje, of een relatie die wijzigt tussen twee domeinobjecten. Niet ongewoon hoor, zo’n kleine wijziging. Gemiddeld wijzigen de requirements gedurende een project ongeveer 20%. Het is voor de ontwikkelaars niet te hopen dat dit ooit gebeurt. Hoe vindt je nu terug welke methoden en queries door zo’n wijziging worden aangetast? Je zult deze applicatie maar in onderhoud hebben. Yoga, vroeg naar bed en veel water drinken!

Globaal
Globale variablen! Altijd goed. Ze zijn er vast.

Dim strQuery As String

Maar die variable strQuery heb ik toch al eerder gezien? Inderdaad. Het is de string waarmee alle tweeennegentig queries in de code behind page worden opgebouwd. Pardon? Inderdaad, vrijwel alle queries die worden opgebouwd in de code starten als volgt.

strQuery = ""
strQuery = strQuery + "SELECT " + vbCrLf

Ik heb het niet durven controleren, maar wat gebeurt er als een van de ontwikkelaars per ongeluk het bovenste van de deze statements vergeet? Je moet er niet aan denken. Zijn de ontwikkelaars misschien niet bekend met lokale variabelen?

Absent
Toch eens kijken naar de oorzaken van deze brei. Wat zegt Anti-Patterns? “Lack of (any) architecture. The absence of definition of the system components, their interactions, and the specific use of the selected programming languages.” Dat is hier op zijn plaats. Ik denk dat met het introduceren van een eenvoudige meerlagenarchitectuur hier veel te redden valt. Een laag voor de webpagina, een laag met domeinobjecten en domeinlogica (of met een hip woord: services) en eentje voor de interactie met de database. Dat zou al een hoop ontrafelen. Anti-patterns geeft nog een interessante oorzaak: “A migrated legacy design that has not been properly refactored into an object-oriented architecture.” De spijker op zijn kop. Ik vermoed dat de code afstamt van Visual Basic Classic – en de ontwikkelaars ook.

Wat een heerlijk fris begin van het nieuwe jaar. Een citaat borrelt op. “I love the smell of napalm in the morning”. Er is nog een hoop werk te doen in 2008!

Implementing value objects in C#

Earlier this year I wrote an article on how to implement value objects (as mentioned by Martin Fowler en Eric Evans in their books, respectively Patterns of Enterprise Application Architecture and Domain Driven Design). It appeared in English in International Developer Magazine (from Australia), and was later translated into German to appear in ObjectSPECTRUM. Finally it now also features in Microsoft’s .Net Magazine in its Dutch translation – which I reviewed before print, and which is a slightly better article than the original English one.

Anyway, download the Dutch PDF here: Value objecten implementeren or visit the Microsoft site (also the Dutch version): Implementing value objects. Quick wins in domain driven development.