views:

553

answers:

1

Hi,

I'm trying to build a document management system and despite all the thigns i've read about entities, value objects, how to choose between how to map them etc... i still can't figure out what the "correct" way to do it is. Quite typically in such a scenerio, each document can beong belong to one or more categories, can be viewed by users belonging to one or more roles etc... So the document entity looks something like this:

public class Document
{
    private int _id;
    private string _title;
    private string _brief;
    private DateTime _publicationDate;
    private string _author;
    private string _source;
    private DateTime _activeDate;
    private DateTime _inactiveDate;
    private IList<Category> _categories;
    private IList<Fund> _funds;
    private IList<Role> _roles;
    ...etc
}

The actual domain mondel and business logic for the application is currently pretty thin so the Category, Fund and Role objects do not contain any business logic and are really just means of categorisation, access control etc (in the case of Roles) etc... In the database therefore, i will have 'Role', 'Category', 'Fund' tables for example and then there will be many-to-many mapping tables with 2 columns: e.g. DocumentId and RoleId. My question therefore is:

Should Category, Fund, Role etc.. be represented in the domain as entities e.g.

public class Role
{
 private int _id;
 private string _name;

 public virtual int Id 
 {
  get { return _id; }
  private set { _id = value; }
 }

 public virtual string Name 
 {
  get { return _name; }
  private set { _name = value; }
 }
}

or as value objects or should the Roles for example just be an enum:

public enum Role
{
    AllUsers
    ,ShareHhlders
    ,Registered
    ,Administrator
}

I started off with the entities approach but now i'm trying to create the 'Add document' functionality and UI and questioning whether it's the right approach - In the add document UI the user gets groups of lists of checkboxes and they pick which categories, roles funds etc... the document will belong to. Onec this information is passed to the controller (i'm using ASP.NET MVC) if a checkbox has been selectd then a category/role/fund etc... needs to be created and added to the document object but to do so the Id of the category/role/fund is needed. It means therefore that i have to possibly maintain mapping objects within the application to get the category/role/fund ids for a given category/rle/fund to pass to the constructors of the category/role/fund objects. This really doesn't seem right and hence why i'm asking the question.

I started to try and change the objects to enums but then the enums and category/role/fund/many-to-many-mapping tables used for referential integrity will need to be maintained separetely. This possibly seems to be a requirement to satisfy persistence yet at the database level i think it's necessary to maintain separate category/role/fund tables, mappping tables and foreign key constraints. (Also using NHibernate for ORM mapping and persistence ut should be able to get it to play nice with enumss).

Thanks

+2  A: 

When choosing between Entities and Value Objects, it's important to determine if the object has a unique identity with internal parts that can be changed. If the object has a unique identity and supports internal changes, do those changes need to be tracked or persisted to the database? In short, do you need to persist CRUD operations on these objects? If so, you may have an Entity. If not, you may have a Value Object.

My gut says that if you could create enums instead of Entities, then you don't need Entity Objects. I vote to use NHibernate to save foreign keys for referential integrity.

Kevin Swiber
Thanks Kevin - At this stage of the application the category/fund/role objects don't have a need to support internal changes/operations. The objects do have a unique identity but it is really only for the purposes of database identity and referential integrity. Based on that, still go for enums and handle the following drawbacks:1. Manually maintain the category/fund/role tables and enums in sink (in the absence of code generation)2. Recompile app for changes to categories/funds/roles.
Matthew
If down the line the app needed to allow for a UI for adding categories/funds/roles by the user then i guess i would have to switch to entities or value objects to support CRUD operations? Would it then be entities or value objects?Any further thoughts?Thanks
Matthew
If the app needs to support CRUD operations for categories, funds, and roles in the future, these should probably become Entities. Value Objects are immutable, disposable objects. Value Objects can be created as components of Entity data, but are themselves not uniquely identified as a persistable object in your application code. I hope that helps.
Kevin Swiber
EDIT: These should probably become Entities WHEN that need arrives. http://en.wikipedia.org/wiki/YAGNI
Kevin Swiber