Click here to Skip to main content
13,860,973 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

11K views
3 bookmarked
Posted 17 Nov 2015
Licenced CPOL

Anemic data models (ADM) VS Rich Data Models (RDM) in C#

, 17 Nov 2015
Rate this:
Please Sign up or sign in to vote.
Anemic data Models (RDM) VS Rich Data Models ( RDM) in C#

What are anemic data models?

What are Rich Data models ?

Anemic data model VS Technical concerns

3 big Complaints about Anemic model

Anemic model in disguise of IOC and DI

Conclusion

Further references and reading

What are anemic data models?

Anemic in English means plain so Anemic Models means plain Models.

Plain models are classes without business logic / behaviors. For example below is a simple “Customer” model which just has the data (properties) but it does not have business logic (behavior).

class Customer
    {
        private string _CustomerName;

        public string CustomerName
        {
            get { return _CustomerName; }
            set { _CustomerName = value; }
        }
        private string _CustomerCode;

        public string CustomerCode
        {
            get { return _CustomerCode; }
            set { _CustomerCode = value; }
        }

    }

Now in real world plain models are of no use without business logic unless you are creating DTO ( data transfer objects) which are meant for different purpose. Some developers feel comfortable in pushing these actions and methods in a separate classes which are named with different vocabularies like service, façade , manager , utility etc. These plain models are then passed to these classes who run the behavior over them.

For example below is a simple service class which validates the “Customer” object and decides if the object valid or not. Putting in simple words Anemic model has behavior in separate service / utility / manager classes.

class CustomerValidationService
    {
        public bool Validate(Customer obj)
        {
            if (obj.CustomerCode.Length == 0)
            {
  return false;
            }
            if (obj.CustomerName.Length == 0)
            {
                return false;
            }
                return true;
        }
    }

What are Rich Data models ?

Rich data models have both data and behavior in the same class. Below is the RDM for the previously defined ADM. You can see the data ( CustomerCode and CustomerName) and behavior (Validate) both are part of the same model.

class Customer
    {
        private string _CustomerName;

        public string CustomerName
        {
            get { return _CustomerName; }
            set { _CustomerName = value; }
        }
        private string _CustomerCode;

        public string CustomerCode
        {
            get { return _CustomerCode; }
            set { _CustomerCode = value; }
        }

        public bool Validate()
        {
                if (CustomerCode.Length == 0)
                {
                    return false;
                }
                if (CustomerName.Length == 0)
                {
                    return false;
                }
                return true;
          
            
        }
        
    }

Anemic data model VS Technical concerns

Lot of developers confuse Technical cross cutting concerns with Anemic model. In Anemic model the behaviors in the service class is the behavior of the real world model.

Lot of developers create utility or service classes which decouple technical behavior from the model which is not anemic model. For example someone can create a “Dal” class as shown below and pass the “Customer” object to be inserted in to the database. Lot of people term this kind of approach as “Repository” pattern.

class Dal
{
        public void InsertDb(Customer obj)
        {
            // Code of ADO.NET goes here
        }
}

Now this kind of model is not anemic model. This is separating the technical behavior from the business behavior which perfectly makes sense. In the previous example we had “validate” method which actually belongs to the “Customer” model. So Anemic model are those models which have business behavior separated in a different class and not technical behavior. So the above “Dal” class is not an Anemic model.

Customer cust = new Customer();
cust.CustomerName = "Shiv";
Dal dal = new Dal();
dal.InsertDb(cust);

3 big Complaints about Anemic model

Lot of developers unknowingly follow Anemic model because of simplicity, but OOP community has the below concerns for ADM:-

  • Anemic model disrespects OOP concepts. Objects in OOP have data and behavior. Object should model real time entity. By separating the behavior we are not following OOP. With behaviors residing in a separate class it would be difficult to inherit , apply polymorphism , abstraction and so on.
     
  • Anemic models can have inconsistent states at any time. For example see the below code we have first created a valid customer object and the validation service logic ran over it and set the “IsValid” to true. So till step 1 everything is fine “IsValid” is true and in synch with the customer object data. Now somewhere down the line you can say in step 2 customer name property is set to nothing. In this step the customer object is not valid in reality but if you try to display in Step 3 it shows valid. In order words the data and the IsValid flag is not in synch
Customer obj = new Customer();
obj.CustomerName = "Shiv";
obj.CustomerCode = "1001";

CustomerValidationService validationService = new CustomerValidationService();
validationService.Validate(obj);
Console.WriteLine(obj.IsValid); // Step 1 :- till here Valid

obj.CustomerName = ""; // Step 2 :-  we made the model invalid
Console.WriteLine(obj.IsValid); // Step 3 :- but it says Still Valid

Anemic model in disguise of IOC and DI

With all respect to the views of OOP developers Anemic models exists very beautifully and amicably in the disguise of DI IOC architecture today. I personally find it very cruel to say it’s an Anti-pattern.

Consider the below scenario where we have a customer class who has different kind of discount calculations. So rather than putting the discount calculation logic inside the customer class you can inject the object from the constructor as shown in the below. In case you are new to dependency injection please read this DI IOC in C#.

class Customer
    {
        private IDiscount _Discount = null;
        public Customer(IDiscount _Dis)
        {
            _Discount = _Dis;
        }
        private string _CustomerName;

        public string CustomerName
        {
            get { return _CustomerName; }
            set { _CustomerName = value; }
        }

        public string Region { get; set; }
        public double Amount { get; set; }
        public double CalculateDiscount()
        {
            return _Discount.Calculate(this);
        }
        
    }

And your discount calculation logic is in a different class all together which takes the customer object for calculating discount.

public interface IDiscount
{
        double Calculate(Customer Cust);
}

Below are two kinds of discount calculations one is a week end discount and the other is a special discount. The week end discount does calculation as per region and week day while the special discount is a 30% flat.

Now the below classes also follow anemic model because the actions are in a different class but still its perfectly decoupled, valid and OO.

public class WeekEndDiscount : IDiscount
{
        public double Calculate(Customer Cust)
        {
            if (Cust.Region == "Asia")
            {
                if (DateTime.Today.DayOfWeek == DayOfWeek.Sunday)
                {
                    return (Cust.Amount * 0.20);
                }
            }
            return (Cust.Amount * 0.10);
        }
    }
    public class SpecialDiscount : IDiscount
    {

        public double Calculate(Customer Cust)
        {
            return (Cust.Amount * 0.30);
        }
    }

Conclusion

  • Anemic data model is a simple plain model class with only data and behavior resides in a separate class.
  • Rich data model have both data and behavior.
  • Anemic model is criticized for not been OO , extensible , inconsistent and follows procedural programming approach.
  • Anemic model should be confused with cross cutting concern technical classes like Logging , Repository etc.
  • DI IOC indirectly forces anemic model. So Anemic model in today world is very much present in the disguise of DI IOC.

Further references and reading

I have been writing a lot on design patterns, architecture, domain driven development and so on. So below are the link feel free to read and do give feedback.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author


You may also be interested in...

Comments and Discussions

 
SuggestionMessage Closed Pin
3-Jun-18 23:51
memberApporva Jain3-Jun-18 23:51 
GeneralEvolution is the key Pin
cheints18-Nov-15 7:25
membercheints18-Nov-15 7:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.190214.1 | Last Updated 18 Nov 2015
Article Copyright 2015 by Shivprasad koirala
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid