Friday, August 27, 2010

Fluent Assertions 1.2.3 released

After a week of testing in some of our projects, it is time to remove the beta marker from release 1.2.3 of our fluent assertion framework, Fluent Assertions. It’s just a small release, as was the previous one, but it still adds some nice additions requested by the community. This is the official list of changes:

  • Added an As<T>() extension method to downcast an object in a fluent way.
  • Added a ShouldNotThrow() and ShouldNotThrow<TException>() extension method for asserting that a (particular) exception did not occur.
  • Fixed a NullReferenceException when comparing the properties of an object to the null-valued properties of another.
  • Fixed an IndexOutOfRangeException when comparing an empty collection with another for equality.
  • Fixed a bug where two equivalent collections that contained duplicate items were not seen as equivalent
  • Minor improvements to the verification messages.
  • Refactored the internal structure of the exception-related assertions, and removed an extra layer of inheritance. Should improve the extensibility.

As usual, you can download Fluent Assertions 1.2.3 from its resident CodePlex site.

Wednesday, August 25, 2010

ALM Practices Part 11: Modeling the business domain using Domain Models

What is it?
A domain model is typically depicted by a UML class diagram in which the classes and associations represent the business concepts and the relationships between them. Although you can use a piece of paper to draw up a domain model, in most cases a UML case tool is better suited for that. Business concepts such as orders, customers or contracts are represented by classes stereotyped as entity. Associations are used to illustrate the roles which that entity fulfills in in the relationship with other entities. An example of a domain model representing a recipe registration application might look like this:
clip_image002[7]
Why would you do it?
  • Because a domain model centralizes the concepts and behavior of the business domain at one place
  • Because while creating it, you'll run into many new important questions on both the static and dynamic aspects of the domain, including constraints, relationships, the business process, roles and responsibilities
  • Because it can be used to verify that the developers and other team members have the same view on the domain as the business people have.
What’s the minimum you need to do?
  • You should clearly communicate that the domain model should not be confused with a data model. It does not imply anything about the database schema and should not contain specific decisions or changes because of that database.
  • Make sure all entities, association roles, attributes, operations and other documentation comply with the Ubiquitous Language.
  • Write in your native language, unless company policy says otherwise.
  • Avoid bidirectional associations. It makes understanding the life cycle of related entities more difficult and introduces technical complexity that ripples throughout the entire system. I also found that bidirectional associations reduces the obviousness of the user interface, because a bidirectional relationships clouds the parent-child obviousness.
  • Always use directional associations. Base those on the conceptional relationship between the entities, not on the way you intend to query the domain for presentation purposes.
  • Always add roles to your associations. They may seem obvious, but by thinking about the role, you may find misinterpretations or an opportunity to get more insights in its purpose.
  • Don't specify a multiplicity of 1, but always specify the others explicitly.
  • Use a composite association when the child's lifecycle is dictated by the parent (like the Recipe-Ingredient association).
  • Don't include any technical terms or .NET-specific types such as string or integer. Use text, number, money or another type from the Ubiquitous Language instead.
  • Make sure that the individual class models are small and do not show more than what the model is intended for.
  • If an entity has a status attribute, carefully consider what impact each status has on the editability and associations of that entity. If these constraint become very complex, consider modeling the State Pattern or choose a design in which every state is represented by a dedicated subclass of the entity.
  • Do not include mutual exclusive associations. If you need these, your entity is probably representing multiple conflicting concepts and should be split up in multiple entities. Again, if these are related to a status attribute, see previous remark.
What’s the usual thing to do?
  • Group related entities that change together, have a dependent lifecycle or form a conceptual whole into a so-called aggregate and choose one entity as the entity that controls access to the others. This is called the aggregate root.
  • My rule of thumb for finding the right aggregate roots is to create a diagram that only contains the aggregate roots. That diagram should include the most important concepts of your domain and clearly illustrate its dependencies.
  • Include detailed constraints on the maximum length of text attributes, ranges of numbers and dates.
  • If such constraints tend to repeat itself for the same kind of data (e.g. an email address, ISBN number, credit card number or currency), consider introducing new classes representing domain-specific primitives with the associated constraints. Stereotype these as a value object and use them instead of primitive types. For instance, the above domain model relies on the following value objects.
image
  • If you find that the same set of entities have completely different meanings and dynamics depending on the department or organizational unit you ask, and you don't see a chance to get them aligned, you may need to introduce different domain models per organizational unit. This practice is often referred to as having more than one bounded context. In other words, different organizational units require different interpretations of the same domain concepts.
  • Consider reading InfoQ's Domain Driven Design Quickly to get a quick-start into the world of Eric Evans' Domain Driven Design.
  • Consider using Sparx’s UML case tool Enterprise Architect since it can generate Microsoft Word documents and a HTML version of the models, making it easy to share the models with the business people.

Tuesday, August 10, 2010

ALM Practices Part 10: Work Item Tracking

What is it?

Using Team Foundation Server’s User Story, Task and Bug work item types as the central unit of work for all the activities done within a project.

Why would you do it?

  • Because it adds traceability between the functional requirements and the way these requirements have been realized on a technical level.
  • Because it introduces a common view of the project between developers and the business people.
  • Because it allows you to keep track of why certain code changes were made.
  • Because it creates an automatic link between the work items representing functional changes, bug fixes and other code changes and the automatic builds.
  • Because it reduces the chance of ending up with loose ends.

What’s the usual thing to do?

  • Track each and every activity that needs to be done in a project as a work item.
  • Use that work item as a central placeholder for all related communication, code changes, discussions, etc.

How do you do that?

  • Register all functional and non-functional requirements as User Story work items and all bugs as Bug work items.
  • Also include non-coding related activities such as deployment activities, writing documentation, assisting the marketing department and such. This improves the transparency of the work that is done in a project.
  • Break these down into one or more linked Task work items and use these for each and every source control check-in.
  • If you are faced with a research task which is difficult to estimate, consider using a Spike with a time-boxed amount of work.
  • Never check-in anything without associating it with a task.
  • Never check-in anything without providing a clear description describing the set of changes (as Check-In Comments).
  • Use Check-In Policies to require developers to provide the comment and the associated work item(s).
  • Rigorously file all loose ends and ‘things to do at some time’ as a Task, preferably linked to the associated Bug or User Story.
  • Consider adding a custom Storyotype field to the User Story work item type to differentiate between functional and non-functional requirements and to assist in scoping the User Stories.

Tuesday, August 03, 2010

ALM Practices Part 9: Ubiquitous Language

What is it?

The Ubiquitous Language is a unified language consisting of verbs and nouns from the business domain of an enterprise system and should be used by all team members, stakeholders and other involved persons.

Why would you do it?

  • Because it creates a bridge of understanding between the developers and the business people.
  • Because it forces different stakeholders (possibly working in different departments) to use the same name for the same concept.
  • Because it improves the readability of the domain model for both developers and business people.
  • Because it improves traceability from functional design, through the user interface all the way into the details of the code base.

What’s the usual thing to do?

  • Maintain a list of verbs and nouns from the domain and promote its usage during verbal communication, in documentation, in user interfaces, and in the entire codebase.

How do you do that?

  • Let the business people propose a proper verb or noun for the concept.
  • Be aware of the fact that different stakeholders may use the same name for different concepts, or different names for the same concepts. Make sure they choose a single unique name for each individual concept.
  • If a name conflicts with a common engineering concept and serious confusion is expected, consider proposing an alternative name.
  • Unless it is company policy to communicate in English, write your domain model in the native language of the business stakeholders.
  • If your policy is to write code in English and the Ubiquitous Language is in your native language, create a glossary that maps the verbs and nouns from the native domain model into the English translations. Be very pro-active in enforcing these specific translations, because from experience I know developers have a tendency for coming up with alternative translations.
  • Be aware of names that are often used intertwined, but represent the same concept. Force one word for that.
  • Be aware of concepts with multiple intentions. They may be different things and require different entities in your domain model.
  • Also be aware for a concept that appears to have mutual exclusive business rules in different circumstances. In most cases, introducing different concepts (and thus different entities) can prevent significant maintenance burden and confusion.
  • If, throughout the project, you come up with a better name for a concept, make sure you adapt your entire code base, functional documentation and the application itself. If you don’t, you end up with many different names for the same concept, causing significant confusion in the project.