Modeling people and organizations: Class Party

Classes for people and organizations are often modeled incorrectly in object models. These faults cause heavy implementation problems. In this posting I will analyze some legacy models, introduce class Party as generalization of people and organizations and provide some implementation details. Information here is based on my own experience, like always.

Legacy models

Pretty often we can see something like these in legacy object models. I added associations with address classes too because this way you get better picture of problems I will describe.

Person and Company: The Legacy Person and Company: The Legacy

Both of these models introduce some pretty bad problems when we are going to implement these models. Major problem is that we have two classes – Person and Company – and we want to use them in same contexts. Their separation introduces additional association on the left model and one additional class with association on the right model. Let’s see one scenarios where problems occur.

Handling Person and Company as one

It is pretty common requirement. We may sell products to persons and companies, so they can be both our customers. We need simple dropdown list on order form to let sales person select customer. This is easy thing to do (although the solution looks awful to me):


SELECT
    'P' + CAST(id AS varchar(8)) AS customer_id,
    last_name + ', ' + first_name AS name
FROM
    person

UNION

SELECT 
    'C' + CAST(id AS VARCHAR(8)) AS customer_id,
    name
FROM 
    company

ORDER BY
    name

This SQL contains something I don’t like. Take a look at these ID-s. These ID-s must contain something we can use when we save customer data. We have to know which table has this ID so we can ask person or company and then assign it to appropriate property of order.

  1. Get customer ID
  2. Determine customer type
    1. If customer is Person
      1. Extract ID
      2. Ask Person with specified ID
      3. Assign it to Person property of Order
    2. If customer is Company
      1. Extract ID
      2. Ask Company with specified ID
      3. Assign it to Company property of Order
  3. Save Order

Well… we got it done but taste of something awful is in mouth.

Generalizing people and organizations: class Party

People and organizations can be handled as parties of different deals. Ordering, buying, signing a contract – all these activities are made by different parties. We can generalize people and organizations using class named Party. You can read more about it and other related models from The Data Model Resource Book – Universal Data Models. I suggest you to buy these books because they help you a lot when you analyze or model your applications.

Here you can see class diagram where Person and Category are generalized using Party.

Class Party generalizes Person and Company

Class Party helps us a lot. All associations that are common for people and organizations we can define between Party and other classes. This way we can handle people and organizations as they are same.

Implementing Party, Person and Company

You maybe notices that Party has property called DisplayName. DisplayName is important design detail. Besides unique identifier we need also something to show as name when we list parties (we want to select customer from dropdown).

Database

Here is the example of tables in database that support our generalization. Tables shown here are simple and give you the point how to do it.

Database structure for parties, persons and companiesTable party is joined to other tables using one-to-one relationship. Party defines the value of primary key, other tables just use it.

We can also see that display name is field of table party. Why? I have found it very convenient if we can see the name of party when we need to manage data in tables manually. DBA is able to solve different issues faster when he or she has all the information that describes rows in table.

Of course, not using the display name in database level is also allowed. Just make your decision considering your current context and needs.

Code

On the code level we have to do some tricks. We define DisplayName as abstract property in Party. Person and Company both have override for this property. Setter of overridden properties is empty because we don’t want to let users change DisplayName manually.


public abstract class Party

{

    public virtual int Id { get; set; }

    public abstract string DisplayName { get; internal set; }

}

 

public class Person : Party

{

    public virtual string FirstName { get; set; }

    public virtual string LastName { get; set; }

 

    public override string DisplayName

    {

        get

        {

            return LastName + ", " + FirstName;

        }

        internal set { }

    }

}

 

public class Company : Party

{

    public virtual string Name { get; set; }

 

    public override string DisplayName

    {

        get

        {

            return Name;

        }

        internal set { }

    }

}


Now we have successfully implemented basic structure of people and organizations in our code. I have used the same solution actively over past couple of years and I am pretty happy with it.

9 Comments

  • Why the concept "Party" wouldn't LegalEntity or maybe something like Agent be more appropriate ?

    Look at some more models at
    http://edemocrazy.sourceforge.net/apidocs/org/directdemocracyportal/democracy/model/world/package-summary.html

    based on

    http://edemocrazy.sourceforge.net/apidocs/org/directdemocracyportal/democracy/model/core/package-summary.html

  • A little OT, but what software was used to generate the class diagrams?

  • Bob, It looks like the entity designer in VS2008SP1 used to create edmx files.

  • Bob, Chris is right. These images are made width Visual Studio 2008 entity model designer. :)

  • I've always used "Entity" as a top-level organizer for such things; more general-purpose. I guess I'm a little surprised that people are excited by this since it's hardly a new idea: inheritance.

  • I agree with you, Dave. It is not an new idea. But still there are a lot of systems that use different hacks and pretty weird and complex solutions instead of solution I offered here.

    There are even analysts and software designers who stuck in this problem. So I think it is good idea to target some posts to people who don't generalize and inherit things so smoothly than we do. :)

  • Thanks Jordan! :)

    Sometimes trackbacks are not published immediately because of caching. But they work.

  • How would this pattern handle organisation data such as person x works in team a in department b for group c in company d?

    Can class party handle that set up?

    Many thanks
    John

  • Hi,

    The term "Party" is commonly used to describe the ideal database structure for CRM systems designed for the services industry. It is also referred to as a "Party Data Model". Many CRM systems are based on product classes or account classes. Party class however shifts the focus to the individual as the universe center, and enables the storing of all other relevant relationships to the individual. This is common within products such as enCentral from enVisual and is ideal for managing customer or client service organizations.

Comments have been disabled for this content.