Tuesday, January 3, 2012

Simple Circles–Domain Model (Part 1)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. Thus, it is important that the domain model be flexible enough to allow various combinations of entities to be used to support these use cases. For example, in a B2B scenario the notion of a person or a household will not likely be center stage whereas businesses will be. However, a club or sports team will likely interact with individuals and possibly households but not likely with businesses.

Models

Simple Circles - Party ConceptModeling entities such as Person, Household, and Organization come to mind immediately. However, the “Party” model has existed for many years as a way to generically model the relationships between various parties. The figure to the right illustrates graphically this concept. Person, Household, and Organization are all types of parties. This approach also allows reuse of relationships such as notes, postal addresses, and communication channels across all types of parties. Rather that duplicating logic, storage mechanisms and business rules for each entity this approach follows the Don’t Repeat Yourself (DRY) principle.

Simple Circles - Party Class DiagramTransferring the conceptual model to a physical one is accomplished using inheritance as shown in the class diagram to the right. The Party class is an abstract base class containing a PartyId unique identifier and a PartyName. Person, Household, and Organization all inherit these base properties supplementing them with specific properties they contain. Notice that the base class contains relationships to Party Note, Postal Address and Channel Address as well as to Party Type. Through inheritance all child subtypes also inherit these relationships without having to explicitly code them three different times (DRY!). Using a separate Party Type allows classifying individual party instances which supports filtering the parties in lists, views, etc.

Classes

Here is the code for the Party class which realizes the class diagram shown above:
namespace Circles.DomainModel
{
  using System;
  using System.Collections.Generic;

  /// <summary>
  /// An abstract class representing any 'Party' that can be interacted with.
  /// </summary>
  public abstract class Party
  {
    private ISet<ChannelAddress> channelAddresses = new HashSet<ChannelAddress>();
    private ISet<PartyNote> notes = new HashSet<PartyNote>();
    private ISet<PostalAddress> postalAddresses = new HashSet<PostalAddress>();

    /// <summary>
    /// Gets or sets the unique identifier of the Party instance.
    /// </summary>
    public Guid PartyId { get; set; }

    /// <summary>
    /// Gets or sets the name of the Party instance.
    /// </summary>
    public virtual string PartyName { get; set; }

    /// <summary>
    /// Gets or sets the PartyType of the Party instance.
    /// </summary>
    public virtual PartyType PartyType { get; set; }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<ChannelAddress> ChannelAddresses
    {
      get { return this.channelAddresses; }
      set { this.channelAddresses = value; }
    }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<PartyNote> Notes
    {
      get { return this.notes; }
      set { this.notes = value; }
    }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<PostalAddress> PostalAddresses
    {
      get { return this.postalAddresses; }
      set { this.postalAddresses = value; }
    }
  }
}

Note that this is not the “finished product” but rather an early version along the way. Future articles will refine this further.

The source code for this article can be downloaded from here.

Next we’ll look at persistence of this model.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.