My thoughts on Value Object

  • Value object has no identity (or its id has no domain meaning), the equality is decided by their values, (not id), which makes it immutable, changing the value of a value object means (equal) to delete it and add a new one. (This rule apply to value object list as well) Here comes the huge benefit, we can add all validation code right in ctor. Once value object has been successfully created, it must be in valid status. (We have to throw exceptions in ctor?)
  • If we found a “Value object” should be updatable, it’s an entity with a value object component. Watch out, value object can have action methods, like Money.Add(Money), this looks like making the modification on the old one, but it returns a new Money internally.
  • According to the rule, value object can’t exist by itself, must live with its owner. But sometimes we need a maintaince app to admin value objets, like lookup, dictionary stuff (coutry list), I think I have to create avalue object repository, with no update() in it.
    Note: UpdateAll() is doing delete all and add all, who cares the id stuff, we only care values.
    Even value object overrode Equals() method, linq.Distinct() is not calling it! Here is the post giving out the workaround.

         public interface IMyValueObjectRepository<T> where T: MyValueObject<T>
        {
            IEnumerable<string> FetchAll();
            IEnumerable<T> FetchAllForEditing();
            void AddNew(T objToAdd);
            void Delete(T objToDelete);
            void UpdateAll(IEnumerable<T> list);
            T FetchByValue(string value);
        }
    
        [Serializable()]
        public abstract class MyValueObject<T> : IAuditable , IEquatable<T> where T : class
        {
            protected MyValueObject()
            {
                CreatedAt = MyDateTime.Default;
            }
            public virtual DateTime CreatedAt { get; set; }
            public virtual string CreatedBy{ get; set; }
    
            public new abstract int GetHashCode();
            public abstract bool Equals(T other);
    
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj)) return false;
                if (ReferenceEquals(this, obj)) return true;
                return Equals(obj as T);
            }
    
            // subclass can also implement static operator == and != inside their own class defination
            // see example http://davybrion.com/blog/2009/03/implementing-a-value-object-with-nhibernate/
        }
    
    
  • Value object can be stored into a separated database table with an id column, we can create a protected internal property in it to hide from external users and enable Fluent NHibernate mapping.
  • Most of time value object is embedded in an entity, probably stored in same database table as parent entity, e.g., address, amount. One-to-One.
  • Value Object has different purpose than DTO, but I just found out it’s very convenient to combine those two in one class, so the same validation rule can be shared between server and client in WCF application.
  • We can create a custom list type instead of IList to do the duplication and minim check in ctor.

A interesting question:

I have a lookup list, try to make it value object. Everything works OK until I try to add an “Active” flag on it.

Does this request change it to entity? At least this value object looks like not immutable anymore. Its active flag can be turn on and off, but for me it’s the same object doesn’t matter it’s on or off.

OK, think about turn flag on and off, I think this is same as Money.Add(), (shown in here P. 49 ) turn on/off a value object is no difference than delete the old off/on value object and insert the new one. Good, it’s still immutable.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s