I was having a think tonight while pondering over some application I need to change and it got me thinking. Entity Framework Entities are POCO (Plain old CLR Objects) and models used in ASP.NET MVC are usually also POCO. This basically means just properties, no methods.
Now OO programming normally allows an object to encapsulate its functionality, which includes its properties as well as its methods, this allows for polymorphism to happen. With the rise of POCO classes being used, design patterns like generic repositories have become more popular. When in the past my objects would have had their own CRUD operations, I now have them on a repository.
Is this just an evolution in OO where CRUD operations are removed from the objects to allow them to be decoupled or maybe CRUD operations shouldn't have been at object level in the past and I was in the wrong? heck, maybe both are perfectly legit and always have been. Its just an observation that got me thinking, so figured I would seek other opinions.
4 Answers 4
As Wyatt said, POCO and POJO in no way implies no methods. I think that stems from not knowing what non-POCO and non-POJO is.
First versions of ORM technologies weren't POCO and POJO simply because it required the entities to inherit some base class from the framework itself. In case of Java, Entity Beans .In case of Entity Framework, POCO wasn't possible in very first version and each entity was required to inherit Entity
base class.
This requirement created dependence of your data model on the persistence technology, which makes lots of things hard or impossible. Things like unit testing the model requires mocking the bean/entity framework which proved to be practically impossible. You also cannot use the model with different persistence technology or you cannot use the model in different context, like in mobile environment.
So your assumption that POCO is about non-existence of methods is wrong. POCO is about being able to use the model in separation from it's persistence technology.
What you are talking about is probably closes to Anemic Domain Model vs proper domain model.
-
You are right, it does look more like the Anemic Domain Model having read that article.Lotok– Lotok2013年12月27日 10:32:26 +00:00Commented Dec 27, 2013 at 10:32
POCO in no way implies there are not methods -- though most of the examples one sees use much of the MVC auto binding features that mainly deal with properties and ignore methods.
Having persistence embedded in your model objects violates separation of concerns and makes it very hard to do things like unit test the objects without standing up a database. It isn't a function of the model object but a function if a different class such as a repository.
-
Eh? poco totally implies no methods in my experience - otherwise it's an entity or model or view model depending on use.Telastyn– Telastyn2013年12月26日 23:35:31 +00:00Commented Dec 26, 2013 at 23:35
-
2Last time I checked a Plain Old C-Sharp Object could have methods. The term came about in the baddish old days where you had stuff like typed datasets or otherwise had to have your model objects inheriting from specific classes and not being POCOs.Wyatt Barnett– Wyatt Barnett2013年12月27日 05:34:05 +00:00Commented Dec 27, 2013 at 5:34
-
The separation of concerns could be achieved while keeping the method on the object, by having the method accept an interface. That interface would specify a type which can handle CRUD operations for the object.Lotok– Lotok2013年12月27日 11:35:27 +00:00Commented Dec 27, 2013 at 11:35
Just two different approaches each with their own merits.
https://stackoverflow.com/questions/1519669/data-access-layer-or-having-object-with-crud-methods
I've been using Extension Methods for stuff like this lately.
The POCO contains logic which only makes sense for the object itself. Business logic or coordinated object logic goes into a BL extension. Data access can go either into a data access layer or a data access extension.
namespace MyApp
{
public class MyClass
{
public string id;
public string name;
public int quantity;
public decimal price;
}
}
namespace MyAppBL
{
public static class MyClassBL
{
public static decimal PriceInCart(this MyClass myObject)
{
return myObject.quantity > 10 ? myObject.price * 0.9m : myObject.price;
}
}
}
namespace MyAppDA
{
public static class MyClassDA
{
public static void Create()
{
...
}
public static void Read(string myObject)
{
...
}
public static void Update(this MyClass myObject)
{
...
}
public static void Delete(this MyClass myObject)
{
...
}
}
}
This give you a very nice myObject.PriceInCart()
and myObject.Save()
while keeping your class focused on the data. Of course for static methods you need to have MyAppDA.Create()
instead of MyApp.Create()
.
Explore related questions
See similar questions with these tags.