0

Why a Product object, for example, has a method called Save?

It seems to me that it is wrong for a Product saving yourself in the database. A product should not only know only about their own responsibility? Did I not understand the purpose of AR or the problem is not in my interpretation?

$product = new Product();
$product->name = 'sample post';
$product->price = 10;
$product->save();
Maykonn
  • 2,738
  • 6
  • 33
  • 51
  • It is called "Active Record". Is `save()` not a reasonable method/behavior of a record? Active Record is intended for largely-passive data, where the only behaviors are load & save. Anyway, your idle musings are not gonna change the design of MS's library. Use it or choose an alternative. – Thomas W Aug 28 '13 at 02:11
  • Product is a Record? In domain is a Entity. Just in database is a Record. I'm not trying to change the Active Record. I'm just understand that he should not enter the field of application(domain), it seems to me that should be used in another context ... It's a feeling I'm having. – Maykonn Aug 28 '13 at 02:20
  • Your concerns are appropriate. To separate concerns, the Data Mapper pattern can be used (http://www.martinfowler.com/eaaCatalog/dataMapper.html). – David Osborne Aug 28 '13 at 09:37
  • 1
    I probably prefer using a Persistence Layer (Hibernate, NHibernate) myself. But I write complex applications with advanced UI parsing & optimized loading schemes.. at a certain level, there can be overlap between domain & storage. I just get on with it. – Thomas W Aug 28 '13 at 11:31
  • Why do you think this violates the SRP? The active record does have a single responsibility: loading data from and persisting data to the database. – Jon Aug 28 '13 at 11:45
  • @Jon But to have only one responsibility, should only load data from and persist - and this are two, no? - data to the database. But if Active Record knows about properties that are saving or persisting, she's doing too much. Remember that I am not saying what is right or wrong, just want to find out if my interpretation of Active Record is correct and if not, I want to know what is right. – Maykonn Aug 28 '13 at 11:59
  • 2
    @MayW.: That's a needlessly literal definition of "one responsibility". By that logic, no class should ever have more than one method because two methods mean it can do two things, so it has two responsibilities. Obviously doing that is noone's definition of good engineering. I also don't follow how knowing about what needs to be saved is doing too much. By definition, *any* code that ultimately saves stuff to a database needs to know about the stuff that gets saved. – Jon Aug 28 '13 at 12:03
  • No, definitely a class has two methods does not mean having two responsibilities. But have two methods that do very different things, as a method to persist in the database and another to change the value of an object property - setAttribute($name, $value) for example - yes. – Maykonn Aug 28 '13 at 17:20
  • I was horrified when I saw that my Product object has method to delete a line that represents it in the database. Thinking in the database, it is as if a line could remove herself. – Maykonn Aug 28 '13 at 17:30

1 Answers1

2

The general principle of Active Record is that an instance of an object is a single row in the data store and the object is wholly responsible for the persistence of itself.

The object has a single responsibility and that is manage the persistence of itself.

Martin Fowler says it best:

An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.

An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database. Active Record uses the most obvious approach, putting data access logic in the domain object. This way all people know how to read and write their data to and from the database.

Community
  • 1
  • 1
qujck
  • 14,388
  • 4
  • 45
  • 74
  • Answered my questions: "An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data..." and "Active Record uses the most obvious approach, putting data access logic in the domain object. This way all people know how to read and write their data to and from the database." I do not like objects that know too much. I would separate it all: "An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.", but that I would be Data Mapper, right? – Maykonn Sep 03 '13 at 17:59
  • @Maykonn I guess you're talking about POCO's that only hold the data about themselves and optionally have links to the data they are related/connected to. The data mapper is the object that maps from the POCO to the data base. – qujck Sep 03 '13 at 18:06
  • Yes! POCO's is that I seem correct. But of course AR is more obvious. And when your framework offers it saves you time. – Maykonn Sep 03 '13 at 18:18
  • Then Active Record should not have domain logic? But, if we follow the SRP, we would need two objects, eg ProductAR and ProductBusiness? – Maykonn Sep 03 '13 at 19:09
  • 1
    In Active Record you have an object that is responsible for one thing - itself and that is the objects only responsibility. The fact that it contains domain logic and can initiate operations on the database doesn't mean it violates SRP - it's single responsibility is to itself. – qujck Sep 03 '13 at 19:13
  • In fact, I can understand your point of view. However, I think the operations database, when complex, can pollute the business rules. The correct, is not keeping the Active Record outside the application domain? – Maykonn Sep 03 '13 at 22:01