Modelus Specification 2.0 is released

We released a new version of Specification. Download it here. With this new release, we added support for .NET 4.0, .NET 3.5, and Silverlight and provided a number of pre-created collection specifications. Happy coding!

June Architect: Domain Model Structure - Part 5: Loading Value Objects into Memory

In my last article, we talked about Value Objects, domain model elements with no conceptual identity. We said that Value Objects represent descriptive aspects of the domain and are fully defined by their state. This month, we will review the options for loading Value Objects into memory.

Potluck Principle of getting Value Objects

The Potluck Principle states that if you need to obtain a Value Object in your code, you have the following three options:

  1. You may be able to create the Value Object yourself
  2. You may be able to ask another object to give the Value Object to you
  3. You may be able to reconstitute the Value Object from a previously stored state

Option 1: Create Value Objects yourself

You can create a Value Object by calling it's constructor or factory. This is a very simple method but there is a catch: since Value Object are immutable, you need to know all their required attributes at the moment of construction.

Example: Creating an instance of the Address class based on a submitted HTML form.

Option 2: Ask other objects to give Value Objects to you

If you need a Value Object in your code, who could you ask for it? Since Value Objects are often descriptors, you may be able to query objects their describe (usually Entities or other Value Objects).

Example: asking Person Entity for the Person's Age or asking Email Address Value Object for it's Domain.

Another popular way is to obtain a Value Object as a result of an operation call closed under the Value Object interface.

Example: (new Money($10)).Multiply(2) results in new Money($20) or Color.Blue.Mix(Color.Yellow) returns Color.Green.

Option 3: Recreating a Value Object from a previously stored state

As discussed in my previous posts, Value Objects are tracked only as part of Entities they describe, in which case they are loaded into memory using Option 2. Value Objects are not recreated from previously stored states.

However, there is a situation when Value Objects need to be created independently. For example, it is a fairly common requirement to display the list of Value Objects in a drop-down list.

Example: User submits a new Purchase Order. As part of the entry screen, the user chooses Billing and Shipping Address for the new Purchase Order. All 50 States are selectable on the Billing Address form, but only 48 States are selectable on the Shipping Address form.

How shall we populate drop-down lists of 48 and 50 States for the New Purchase Order screen?

I have heard software designers making arguments towards promoting State to an Entity. Then, State Repository would be responsible for retrieving the right lists of States to display in each situation. I disagree with such design. It introduces a responsibility of managing States into the domain model, which can be easily avoided if we keep States as Value Objects.

Another important point against introducing the IStateRepository interface is that business rules of whether to display a particular State in a drop-down or not do not belong to the State class. For example, the company could introduce a new Product, which could be shipped to all 50 States.

My preference is to assign the responsibility of knowing about Value Object lists to aggregate repositories. In our example, IPurchaseOrderRepository would have FindStatesForShipping and FindStatesForBilling methods.

Happy coding! To be continued...

March Architect: Domain Model Structure - Part 4: Value Objects

In the Part 2 and Part 3 of the Domain Model Structure series, we continued our discussion around how to organize classes inside your domain model. We defined Entities, looked at their relationships, and reviewed options for loading them into memory. This month, we will take a look at Value Objects.

Discovering Value Objects

Value Objects are domain model elements with no conceptual identity. They represent descriptive aspects of the domain and are fully defined by their state. Their behavior depends on what they are, not who they are. If they need to be tracked, they should be tracked with the elements they describe. Thus, they do not need an identity of their own.

We prefer to keep Value Objects immutable, i.e. changeable by full replacement only. Immutable Value Objects are safe to share (which increases performance), and easy to understand (which allows you to build complex behaviors). Let me give you an example based on a classical OO problem:

Assume you have two buckets of paint: b1 and b2. The first bucket b1 contains 1 gallon of yellow paint. The second bucket b2 contains 1 gallon of blue paint. Without looking into the code, could you answer the following questions about the results of the operation b1.Add(b2)?:

  1. What will be returned by the Add method? Is it 2 gallons of green paint or nothing?
  2. What will be in the the first bucket b1? Is it 2 gallons of green paint or 1 gallon of yellow paint?
  3. What will be in the second bucket b2? Is it 1 gallon of blue paint or nothing?

If you notice, we do not have a requirement to track buckets of paint. Thus, I will assume that Bucket is a Value Object and should be immutable. Since both buckets are immutable, they will contain their original values of 1 gallon of paint each and the result of the Add operation will be 2 gallons of green. With no convention in place, it would be impossible to answer these questions without checking the code or better yet unit tests first.

You domain has many Value Objects, a lot more than Entities. If you are having troubles seeing them in your system, take a closer look at the Entities. How are they being described? What are their attributes and properties? How are they being searched for or ordered by? The chances are you will be talking about Value Objects.

Examples: Address, DayPoint, Money, Range, SSN, etc.

Domain Model Structure

Value Objects along with Entities are main elements of the domain model. Many of them are small simple classes that will be widely used in your application. Place them together in a sub-folder under the Domain Model root. We name this folder "Capability":

Domain Model Structure - Capability folder

You are likely to have a number of very complex Value Objects as well. I will try to discuss some of them in my future articles.

Summary and Additional Tips

  1. Never define an identity for a Value Object.
  2. Consider overriding equality operators to match Value Objects using object attributes rather than object references.
  3. Keep Value Objects immutable.
  4. Place Value Objects used across many applications into a dedicated Domain Kernel library.
  5. If you are interested in creating a simple base Value Object class, you can start with the one listed below:

    Domain Model Structure - Value Object Template

Happy coding! To be continued...

January Architect: Domain Model Structure - Part 3: Repositories

Last time, we continued a discussion around how to organize classes inside your domain model. We defined important domain model elements: Entities, aka Reference Objects, and looked at their relationships. This month, we will review the options for loading Entities into memory.

Potluck Principle of Getting Objects You Want

The Potluck Principle states that if you need to obtain a reference to an Entity in your code, you have the following three options:

  1. You may be able to create the Entity yourself
  2. You may be able to ask another object to give the Entity to you
  3. You may be able to reconstitute the Entity from a previously stored state

Choosing the right option

The option #1 is usually implemented via a constructor or a factory. It works well when you need to create a new entity object, not yet tracked by the application.

As we discussed last month, Entities span through long periods of time and run across multiple systems. Unless you are writing a data entry application, you are going to work with existing Entities a lot more often than with new ones. When you need to create an existing Entity, use the option #2 or the option #3.

Let us take a look at the last month's example: User logs in into the system to check the status of their loan applications. Assuming we have a Person loaded, how shall we obtain their Applications?

Entity Relationship

To enable the option #2, design the Person class with a method or property that returns the Person's Applications. I generally prefer to pass a qualifier, such as loan type or date, that would transform one-to-many relationship between Person and Application into one-to-one with a qualifier, but this is a topic for another conversation. For now, let us assume that the Person class defines the Applications property that returns a list of Applications. This requires you to either get the Applications when the Person object is loaded into memory or implement a lazy load mechanism to defer loading Applications until the Applications property is called.

To enable the option #3, design the ApplicationRepository class with a method that returns a list of Applications for a given Person: "IList FindByPerson(Person person)".

Domain Model Structure

Repositories in the Domain Model

My preference is to place repository interfaces in the model and move repository implementation into a separate Persistence library. Keeping repository interfaces in the model helps clients understand how entities are supposed to be loaded into memory. Having repository implementation separate from the model keeps the model free from infrastructural detail.

Happy coding! To be continued...

November Architect: Domain Model Structure - Part 2: Entities

Last month, we started a discussion around how to organize classes inside your domain model in a clear, easy-to-understand, and easy-to-maintain way. We reviewed our objectives and discussed why they are important. This month, we will start revealing a story of a business domain for the purposes of developing a software application. We will look into what is being managed in the domain day to day: Entities.

Discovering Entities

There are a number of technical definitions of an Entity that are popular in the industry. For example, here is a definition from Eric Evans' book Domain Driven Design, p. 89: An object that is not fundamentally defined by its attributes, but rather by a thread of continuity and identity.

The way I prefer to think about Entities is what we manage in our domain day after day. Entities span through long periods of time and run across multiple systems. They often have lives well beyond our applications and must be effectively tracked. As a general rule, assume that mistakes in Entity identification and tracking are expensive to notice and repair.

To discover Entities in your domain, talk to your functional people and end users. Ask them to walk you through scenarios the new system should implement. How are your users going to use your application? What is important to them and why? What do they really care about? What is important to your company and how does it need to be reported? The chances are you will be talking about what needs to be tracked and how, thus you will be talking about Entities.

Examples: Person, Account, Loan, Application, Payment.

Entity Relationships

What are the relationships between your Entities? Before getting into technical details, create a simple analysis diagram that shows the Entities you have discovered and their relationships. Lets consider a simple example:

Scenario 1: User logs in into the system to check the status of their applications and loans.

Scenario 2: User calls a Customer Service Representative (CSR) to reset their password.

Entity Relationship

Your research and conversations about the domain model revealed 4 Entities: Account, Person, Application, and Loan. Let us walk through the first scenario:

  1. User logs in into the system. The system needs to retrieve the user's security Account and verify their username, password, and any additional validation factors.
  2. Upon successful login, the system retrieves a previously stored Person record based on Account information. Thus, you see an arrow from Account to Person. You learned that each Account has a corresponding Person record, but not all People have created an online Account. That explains the numerical values on the diagram.
  3. Based on Person, the system retrieves their Application and Loan information. Thus, the arrows are shown from Person to Application and Loan. Person is created on the system with their first Application, but not all Applications are approved to become a Loan. Notice that there is no arrow between Application and Loan - we cannot determine its direction based on our current scenarios.
Now, let us take a look at the second scenario:
  1. User cannot verify the security information during login and calls CSR to reset their password. CSR asks them a series of Personal questions and retrieves their Person record.
  2. CSR retrieves the user's Account record for additional verification and resetting the password. Thus, you see an arrow from Person to Account.
Do not worry about having a circular dependency between Account and Person on the Analysis diagram. In one of our next articles, we will show several implementation options for the relationships. We will not have a circular dependency in the final implementation.

Domain Model Structure

Account, Person, Application, and Loan are our first classes in the Domain Model. For now, place them together in a sub-folder under the Domain Model root. We name this folder "Operation":

Domain Model Structure - Operation folder

Summary and Additional Tips

  1. Entity is an object that is not fundamentally defined by its attributes, but rather by a thread of continuity and identity.
  2. Entities span through time and space and are being tracked and managed in the day-to-day operations.
  3. Discover Entities by talking to your functional and end users. Create simple Analysis diagrams as a result of these conversations.
  4. Entity's primary responsibility is to maintain its continuity. Keep it simple by leaving complex behaviors out of its class definition.
  5. Managing life-cycle of Entities is a complex and risky job. Try to keep the number of Entities in the system down. Too many Entities will defuse your model and create no value.
  6. Compare Entities of the same type by their identity regardless of their form and history. Make identity type a Value Object.
  7. If you are interested in creating a simple base Entity class, you can start with the one listed below:

    ///<summary>Base Entity Class </summary>
    public class Entity <T>
    {
        public T ID { get; protected set ; }
        public static T NewID { get { return default (T); } }

        ///<summary>Returns true if the object has not being stored in the system. </summary>
        public bool IsNew { get { return Equals(NewID, ID); } }
        public Entity(T id) { ID = id; }
    }

Happy coding! To be continued...

October Architect: Domain Model Structure - Part 1

Problem Statement

In August, I blogged about the structure of a release unit's trunk folder. We looked at how to organize your .NET solution to support principles of object-oriented and domain-driven design and distributed application development. We recommended creating a separate library for domain model classes that would describe your release unit's capabilities in business terms.

This month, we are starting a discussion around how to organize classes inside your domain model in a clear, easy-to-understand and, thus, easy-to-maintain manner that supports natural growth of your applications. The topic is quite large and will take a series of articles to cover even at a very high level. The purpose of this article is to introduce you to the topic and provide basis for our discussion over the next few months.

Objectives

As always, let's define our main objectives:

  • Support on-the-project learning
  • Organize development of the domain model in a structured evolutionary manner
  • Have the domain model tell a story
  • Make rules and operations explicit and extendable
  • Support domain-driven design philosophy
  • Support principles of object-oriented design

Why are these objectives important?

Support on-the-project learning

When all decisions are predetermined before the implementation, a significant amount of business value is lost:

  1. Learning that occurs during the project is ignored because it is not a part of the original plan.
  2. Communication between users and stakeholders and the development team is poor.
  3. Very limited creativity takes place. There is almost no place for new ideas.
  4. As a result, the system is created lacking flexibility and understanding of the domain.
To get the most out of your projects, enable continuous functional and technical learning for all your team members. As they learn more, they will make decisions better and faster.

Organize development of the domain model in a structured evolutionary manner

There are two major alternatives to Structured Evolutionary Design:

  1. Big Design Up Front (BDUF), in which design decisions are perfected before the implementation is started.
  2. Adhoc Evolutionary Design, in which design decisions are made as the system is being developed, but without a set of rules that would ensure domain model consistency.
As your team acquires new knowledge, their understanding of the domain changes. Even if you start with BDUF, the domain model needs to evolve in order to correctly represent your understanding of the business situation.

As your domain model evolves, it becomes more powerful and sophisticated, requiring you to establish rules and guidelines around it. Without overarching rules, constant changes to the model will make it inconsistent and hard-to-understand, eventually leading to a familiar "fast-slow-stopped-redesign" application development cycle.

Have the domain model tell a story

An ability of the domain model to tell a story is one of the most critical design objectives. OO allows us to build classes representing real-world business concepts. Should not we be able to use them to describe a business situation? Ask the following questions during your next design or code review:

  • What business processes are enabled by this system and what are their steps?
  • What business transactions are supported and how are they implemented?
  • What business concepts do we deal with day-to-day? How are they described? How can they be created and loaded into memory?
  • What operations are performed? What decisions do we face? What business rules could be customized and how are they configured?

Make rules and operations explicit and extendable

Business rules and operations are often the most sophisticated and the most changeable classes in the domain model. But most importantly, these classes have a great potential to add a hidden business value. Make them explicit and extendable in your model to uncover their true power.

Support domain-driven design philosophy

If you are new to domain-driven design, please, refer to this book to get started.

Support principles of object-oriented design

There is plenty of information online about the object-oriented principles. They are a great way to maintain a clear, flexible, reusable, and robust codebase and keep infrastructural details outside of the domain model.

Summary

This article started a discussion around how to organize your domain model. We have reviewed the objectives and discussed why they are important. Next time, we will look closer into designing domain model in practice.

Happy coding! To be continued...

Domain Driven Design at .NET User Group on Thu, October 1, 2009

Jordan Terrell will be speaking on Domain Driven Design tomorrow, October 1, 2009.

Who: Jordan Terrell
What: Introduction to Domain Driven Design
When: Thursday, October 1, 2009
5:00 - 7:00 pm - Presentation
Where: Microsoft Corporation, 8300 Norman Center Drive, Suite 950, Bloomington MN 55437
Cost: Free. Register here.

August Architect: .NET Solution structure

Problem Statement

Last month, I blogged about organizing code in a source control system. We looked at how release units help us represent a domain context map to support domain-driven design and distributed application development. We recommended adopting a standard release unit layout so that your release process can be clearly understood and automated.

This month, we will take a deep dive into the release unit's trunk folder. I said before that trunk contains the latest version of the release unit code. How shall we organize our code inside trunk?

Objectives

As always, let's define our objectives:

  • Support domain-driven design philosophy
  • Support principles of object-oriented design
  • Support distributed application development
  • Support a structured, repeatable, and traceable release process

Release Units in .NET

Release Unit is a collection of folders and files that are released together. In .NET environment, this is achieved with a .NET solution that groups multiple projects together for the purposes of debug, compilation, and release. Hence, if you are working in .NET environment:

Each release unit should contain one and only one .NET solution.

.NET Solution Structure

Now, we are ready to take a look at a sample .NET solution structure that will help you implement principles of domain-driven design and object-oriented programming. For simplicity, let's assume our solution consists of a single web application and a command-line data setup utility. You will have no problems extending this approach to handle your own more sophisticated scenarios.

.NET Solution Structure

/doc - contains release unit's documentation.

/lib - contains release unit's pull dependencies. When your project uses a .NET assembly not part of your solution, place the assembly into the lib folder and reference it from there. It ensures that all projects in the same solution always use the same version of the dependent upon library and provides you with a clear way to upgrade the library to a new version should you decide to do so.

/Database - contains database creation and modification scripts, scripts to set up users and their permissions, load data files, etc. This folder may also include command-line batch files to set up the release unit on a local machine, build, integration or test server.

/Model - contains classes of the Domain Model, a central part of the release unit. This assembly describes what can be accomplished by the release unit in business terms. Keep the model free from infrastructural detail. It will help you achieve high levels of reuse and low costs of maintenance in your applications. Next month, we will take a look at how to organize your domain model to clearly identify all supported business scenarios and transactions. This is a big topic on its own, which certainly deserves a dedicated blog article.

/ModelUT - contains unit tests for the Domain Model classes.

/Persistence - implements a persistence mechanism for the release unit's domain model. I strongly recommend keeping persistence interfaces with the model itself since it shows how aggregates and entities are designed to be loaded into memory. The purpose of the persistence library is to implement persistence interfaces with your standard tools and techniques.

/PersistenceUT - contains configuration files and unit tests for the Persistence. In our case, these tests verify the release unit's persistence classes and their configuration files as well as the database. Strictly speaking, they are integration tests. However for the purposes of the domain modeling, we prefer to think about the whole domian model persistence as a black box.

/WebInfrastructure - contains web infrastructural classes which would otherwise be placed in the App_Code directory on the web site. Extracting these classes into a dedicated library allows them to be unit tested.

/WebInfrastructureUT - contains unit tests for the web infrastructural components.

/Web - contains a web application, a top application layer responsible not only for user interface but also for referencing and configuring all its depencies.

/WebUAT - contains user acceptance test scripts, such as Selenium or WatiN.

/WebLT - contains load testing projects, such as JMeter or LoadRunner.

/DataSetup - contains a command-line process to perform backroom administrative tasks.

/DataSetupUT - contains unit tests for the data setup components.

Dependencies

To better understand this sample solution structure, take a look at the package diagram below:

Package Diagram

Summary

  1. For each release unit, create a .NET solution file.
  2. Place all of your external pull dependencies into the lib folder.
  3. Keep your model classes free from any infrastructural detail.
  4. Make your top layer responsible for connecting and configuring all its dependencies.

Happy coding!

July Architect article updated

Based on the comments received, I have updated my last month's article in the Architect column. In the end of the article, you will now find a 5-step summary on how to structure your source control repository in order to support:

  • Domain-driven design philosophy
  • Distributed application development
  • Structured, repeatable, and traceable release process

Thank you for reading Modelus Blog!

July Architect: How to organize your code in Source Control System

Problem Statement

One of the first questions facing development teams is deciding how to organize their code in a source control system. In this article, I will describe an approach that we have applied successfully at multiple organizations over the last decade. I hope it will help you and your team make your development environment and processes leaner and more efficient.

Objectives

First, let's understand what capabilities we are looking for from our source control system:

  • Support of the domain-driven design philosophy
  • Support of a distributed application development
  • Support of a structured, repeatable, and traceable release process

Release Unit

Our source control system is organized around release units. Release Unit can be thought of as a collection of folders and files that are released (and thus, reused) together. It is a job of application architecture to break down a large monolithic application into multiple release units so that they can be tackled independently by different development teams.

Pull and Push Release Unit Dependencies

We recognize two types of dependencies between release units: Push and Pull. Let's assume that Release Unit A depends on Release Unit B. Push dependency means that every time B is changed, it is automatically integrated with A. Pull dependency means that B is integrated into A when A's development team decides to pull a new version of B into A.

An example of Pull Dependency: an application that depends on a shared domain. Even though a new version of the shared domain may be released each month, it does not force the application to be integrated, tested, and redeployed on a monthly basis. Instead, the application integrates with the shared domain only when the application development team decides to pull a new version of the shared domain into the application.

An example of Push Dependency: a web application that depends on the portal's header and footer. Every time, the new header and footer are implemented, each web application is automatically integrated with the new header and footer code.

Implementing Release Unit

We recommend to store a release unit in its own source control folder with the following layout:

/trunk - contains the latest version of the release unit code (may be in progress)
/tags - contains read-only copies of the code (e.g., previous releases of the code into production or test environments)
/branches - contains branch copies of the code

Implementing Pull Dependency

Create /lib folder in your release unit's trunk and place all release unit's pull dependencies there. Configure your release unit to automatically integrate with the dependencies placed in the lib folder. Next month, I will demonstrate how to set up a sample .NET solution structure with pull dependencies.

Implementing Push Dependency

Configure your release unit to link and automatically check out or export all its push dependencies. In Subversion, this can be achieved by using the svn-externals property.

Organizing Release Units

Even a medium-sized organization is likely to have hundreds or even thousands release units in their source control repository. In order to keep the repository manageable and easy to navigate, group release units belonging to the same bounded domain contexts together. For example, you may have a set of release units stored in the Accounting folder, another set stored in the HR folder, and another set stored in the Finance folder. You will need to refer to your domain context map in order to learn what bounded contexts exist in your organization.

5-Step Summary

  1. Structure source control to represent your domain context map
  2. Develop your applications using multiple release units
  3. For each release unit, assign ownership to a dedicated development team
  4. Integrate release units via Push and Pull dependencies
  5. Establish standard integration and release processes for all release units

Contact me if you have any questions or comments. Happy coding!

Welcome to ModelBlog

Thank you for visiting ModelBlog. We hope the time you spend with us will be both entertaining and worth your while. Have fun!

Authors

Search

Archive

Tags