Active Record vs Objects 105
Active Record is a well known data persistence pattern. It has been adopted by Rails, Hibernate, and many other ORM tools. It has proven it’s usefulness over and over again. And yet I have a philosophical problem with it.
public class Employee extends ActiveRecord {
private String name;
private String address;
...
}
We should be able to fetch a given employee from the database by using a call like:
Employee bob = Employee.findByName("Bob Martin");
We should also be able to modify that employee and save it as follows:
bob.setName("Robert C. Martin");
bob.save();
In short, every column of the Employee table becomes a field of the Employee class. There are static methods (or some magical reflection) on the ActiveRecord class that allow you to find instances. There are also methods that provide CRUD functions.
Even shorter: There is a 1:1 correspondence between tables and classes, columns and fields. (Or very nearly so).
It is this 1:1 correspondence that bothers me. Indeed, it bothers me about all ORM tools. Why? Because this mapping presumes that tables and objects are isomorphic.
The Difference between Objects and Data Structures
From the beginning of OO we learned that the data in an object should be hidden, and the public interface should be methods. In other words: objects export behavior, not data. An object has hidden data and exposed behavior.
Data structures, on the other hand, have exposed data, and no behavior. In languages like C++ and C# the struct
keyword is used to describe a data structure with public fields. If there are any methods, they are typically navigational. They don’t contain business rules.
Thus, data structures and objects are diametrically opposed. They are virtual opposites. One exposes behavior and hides data, the other exposes data and has no behavior. But that’s not the only thing that is opposite about them.
Algorithms that deal with objects have the luxury of not needing to know the kind of object they are dealing with. The old example: shape.draw();
makes the point. The caller has no idea what kind of shape is being drawn. Indeed, if I add new types of shapes, the algorithms that call draw()
are not aware of the change, and do not need to be rebuilt, retested, or redeployed. In short, algorithms that employ objects are immune to the addition of new types.
By the same token, if I add new methods to the shape class, then all derivatives of shape must be modified. So objects are not immune to the addition of new functions.
Now consider an algorithm that uses a data structure.
switch(s.type) {
case SQUARE: Shape.drawSquare((Square)s); break;
case CIRCLE: Shape.drawCircle((Circle)s); break;
}
We usually sneer at code like this because it is not OO. But that disparagement might be a bit over-confident. Consider what happens if we add a new set of functions, such as Shape.eraseXXX()
. None of the existing code is effected. Indeed, it does not need to be recompiled, retested, or redeployed. Algorithms that use data structures are immune to the addition of new functions.
By the same token if I add a new type of shape, I must find every algorithm and add the new shape to the corresponding switch statement. So algorithms that employ data structures are not immune to the addition of new types.
Again, note the almost diametrical opposition. Objects and Data structures convey nearly opposite immunities and vulnerabilities.
Good designers uses this opposition to construct systems that are appropriately immune to the various forces that impinge upon them. Those portions of the system that are likely to be subject to new types, should be oriented around objects. On the other hand, any part of the system that is likely to need new functions ought to be oriented around data structures. Indeed, much of good design is about how to mix and match the different vulnerabilities and immunities of the different styles.
Active Record Confusion
The problem I have with Active Record is that it creates confusion about these two very different styles of programming. A database table is a data structure. It has exposed data and no behavior. But an Active Record appears to be an object. It has “hidden” data, and exposed behavior. I put the word “hidden” in quotes because the data is, in fact, not hidden. Almost all ActiveRecord derivatives export the database columns through accessors and mutators. Indeed, the Active Record is meant to be used like a data structure.
On the other hand, many people put business rule methods in their Active Record classes; which makes them appear to be objects. This leads to a dilemma. On which side of the line does the Active Record really fall? Is it an object? Or is it a data structure?
This dilemma is the basis for the oft-cited impedance mismatch between relational databases and object oriented languages. Tables are data structures, not classes. Objects are encapsulated behavior, not database rows.
At this point you might be saying: “So what Uncle Bob? Active Record works great. So what’s the problem if I mix data structures and objects?” Good question.
Missed Opportunity
The problem is that Active Records are data structures. Putting business rule methods in them doesn’t turn them into true objects. In the end, the algorithms that employ Active Records are vulnerable to changes in schema, and changes in type. They are not immune to changes in type, the way algorithms that use objects are.
You can prove this to yourself by realizing how difficult it is to implement an polymorphic hierarchy in a relational database. It’s not impossible of course, but every trick for doing it is a hack. The end result is that few database schemae, and therefore few uses of Active Record, employ the kind of polymorphism that conveys the immunity of changes to type.
So applications built around ActiveRecord are applications built around data structures. And applications that are built around data structures are procedural—they are not object oriented. The opportunity we miss when we structure our applications around Active Record is the opportunity to use object oriented design.
No, I haven’t gone off the deep end.
I am not recommending against the use of Active Record. As I said in the first part of this blog I think the pattern is very useful. What I am advocating is a separation between the application and Active Record.
Active Record belongs in the layer that separates the database from the application. It makes a very convenient halfway-house between the hard data structures of database tables, and the behavior exposing objects in the application.
Applications should be designed and structured around objects, not data structures. Those objects should expose business behaviors, and hide any vestige of the database. The fact that we have Employee tables in the database, does not mean that we must have Employee classes in the application proper. We may have Active Records that hold Employee rows in the database interface layer, but by the time that information gets to the application, it may be in very different kinds of objects.
Conclusion
So, in the end, I am not against the use of Active Record. I just don’t want Active Record to be the organizing principle of the application. It makes a fine transport mechanism between the database and the application; but I don’t want the application knowing about Active Records. I want the application oriented around objects that expose behavior and hide data. I generally want the application immune to type changes; and I want to structure the application so that new features can be added by adding new types. (See: The Open Closed Principle)
I think this is exactly why I had difficulty when I got assigned to a RoR project. I had an idea of how the objects should work, test drove a nice (well, ok) design and then ran up against how to integrate it into AR.
I would be very appreciative if you could post a follow up on how you would approach bringing AR in as a halfway point between the business object model and the database.
So, if I had a Order with OrderLines. Two active record classes.
They should be wrapped in an ‘BusinessOrder’ class that uses Order/Orderlines as CRUD – the business logic for an order is in BusinessOrder, not in the Order/Orderlines objects.
Am I understanding this correctly?
What about the large number (at least everywhere Ive been) of applications that are primarily CRUD with very little domain logic? Would you still split the ActiveRecord out?
“On which side of the line does the Active Record really fall? Is it an object? Or is it a data structure?”
True. It is indeed a data structure or an object.
“the algorithms that employ Active Records are vulnerable to changes in schema, and changes in type”
When the schema changes in a data-centric app, the behaviors are necessarily going to change. In a data-centric app, the data is a large part of the domain’s identity. It makes sense that these changes happen.
“Those objects should expose business behaviors, and hide any vestige of the database”
Yeah, we can do that, but the cost of making the abstractions that leak-proof would often be prohibitive, unless you’re dealing with a domain with relatively high complexity where applying that much sealant might make the difference between success and failure.
“it makes a fine transport mechanism between the database and the application; but I donÂ’t want the application knowing about Active Records.”
Object-oriented approaches (DDD, for example) are good for tackling complexity. When you don’t have that much complexity to deal with, fall back and DTSTTCPW.
I’m yet to be convinced that Active Record is the simplest thing. How is it simpler than separating persistence concerns into an infrastructure service that we clothe in a repository, assuming that we have frameworks in both cases that do the heavy lifting for us around object-relational mapping. Aren’t we just changing where the implementation lives?
I’m working on a Rails app at the moment where I think this would come in handy with a few design issues I’m having, but I’m missing an implementation step ( I think).
For example. Let’s assume I’ve got your typical Rails MVC setup for a people table. The Model is Person, the controller PeopleController, and the views all stored in the People directory. The controller has methods like person.save! and person.destroy. Now we want to introduce a new layer, so that the Controller deals with a true object, and removes any vestige of the database. What would I name the layer? After all it’s still a Person. You could argue that it’s more a Person than the active record Person, so maybe it should be the model Person with another class called PersonRecord. All the business logic is in Person, and all the database logic is in PersonRecord. Then who calls save? If the controller calls save on person, and person delegates it to PersonRecord, then we haven’t removed database concerns from the application. If the controller doesn’t call save, and Person hides that, then when do saves get called. On every change? This doesn’t even account for the fact that if I did this in my hypotehtical Rails app I’d likely lose a lot of help, as Rails relies on naming conventions to provide it.
The fact is I agree with the ideas behind the essay, so I’m going to try and implement it anyway to solve the real world issue I’m having now, but I’m concerned I’ll be adding extra complexity to the app, and implementing it wrong. Like Steve I may need an example to fully get it.
Bob! You’r perfectly right to have a problem with ARs.
> It has proven it’s usefulness over and over again.
Are you really serious about this? For me, one of the most important parts in your book “Agile Software Development” is the suggestion to start developing the logic before designing the database schema. I proved that for myself in three projects. The schemata turned out to be quite diffrent than we’d expected before, however, they have proven their value ever since.
ARs are quite the opposite of that as they tightly couple the database to the code. Eventually, the database will take hostages. First the application, then each developer working with it. Finally, you spent your time arguing for weeks or even months with database people for even the tiniest change the now “sacret” schema.
To Eric: Did you ever see a person “save” or “destroy” themselves? How many persons you know have business logic inside? What would a person controller look like or do? ;-)
I think Active Record’s problems come from implementing it from the beginning of your project which has the risk of biasing your design towards a weak domain model. You will tend to make design decisions that fit well with Active Record and it will be more difficult to realize you should be refactoring towards having a domain model.
You can’t be sure whether your app will be really data-centric until it’s finished and the most flexible design to cope with this doubt is starting with the simplest domain model. If at the end it gets anemic and you don’t find it’s behaviour outside, possibly in a service layer, then you can substitute it with the data layer, which could be Active Record.
So like Martin’s idea of considering the datalayer as an implementation detail. It may be an important detail, but details don’t belong to abstractions, and if you mix them you fix’em (sorry couldn’t avoid that).
It’s easier to start flexible and then tighten than start tight and then get flexible.
So I think it’s easier to add Active Records to your domain models than adding a domain model to your Active Records. And you’ll have the advantage that you are not tied with a particular Active Record implementation.
I’d use a pure AR solution only if I’m very very sure that I’m dealing with a simple CRUD that won’t change in the future, and even then I’d feel uncomfortable. The application may be data centric now but you can’t be sure if it will keep being that way in the future. You don’t know that even if you are the only client of the app.
Did you ever see a person “save†or “destroy†themselves? How many persons you know have business logic inside? What would a person controller look like or do? ;-)
To Sebastian: No I sure haven’t – but I clearly at some point the data must get saved to the database. Try as I might to avoid that in the controller, and admittedly real life is more complicated than my contrived example, is not simple and causes me to do some things I’m not 100% comfortable with. I’m going to have to continue to work with this idea.
Bob,
I agree with your distinction between objects and data structures, although I don’t see a problem with objects being used as data structures with respect to some operations and objects with respect to others. The Visitor pattern is largely a way to get inside an object and treat it as a struct.
However, wrt the notion that ARs should not be exposed to the application, I would assert that the application actually can’t know whether it’s dealing with ARs or “very different kinds of objects”. The two may be identical in interface. Therefore it’s entirely legitimate to start with a domain model of ARs, and evolve selected classes towards more sophisticated patterns as required. In fact, the decision to make a class persistable should be able to be deferred or changed without disruption to the domain model.
The definition of AR seems to be entirely in terms of implementation – the under the hood fact that instances map to rows and properties map to columns. The existence of save(), findby…() methods etc. merely implies the existence of a shared global namespace, of which an RDBMS is only one example. The save() method may be trivially generating a SQL insert statement from the property list, or it may be an entry point into arbitrarily complex mapping code – makes no difference to the application.
So, while it’s strictly true that algorithms that use AR’s are vulnerable to changes in schema, it’s trivial to decouple an AR from the schema – at which point it’s no longer an AR. Your point remains valid, but maybe it’s not so important to choose up front.
Jaime Metcher
Eric, Sebastian: can a person “save” or “destroy” themselves? Absolutely yes. This is not about philosophy, it’s about information. A person “saves” themselves into various domains when they register to vote, sign up for a mailing list, sign a petition, apply for citizenship. We could come up with all sorts of cute analogies where the immigration clerk is the DAO, etc., but the basic point is that these things are initiated by the person (and indeed some can only be initiated by the person themselves).
What makes an object transient is not that it ceases to “exist”, but that it ceases to be addressable – a “transient” object may live on for decades in some paging file on a tape in a vault somewhere, but good luck finding it. Similarly, a person with no registration of birth, citizenship papers or bank accounts may live a long and full life, but they do not exist in a “persistent scope” and therefore can’t be found by anybody else.
Bob,
I’m not sure whether to agree with you or not as I see problems with both solutions.
With your solution, assume that your database contains a table called Employee. Assume also that you want to have a business object called Employee. The result is duplication: you will have two classes containing the same fields. It exhibits the Fowler code smells “Parallel Class Hierarchy” and “Shotgun Surgery”.
Besides, I thought it was generally agreed that the DTO pattern is an anti pattern.
Bob,
I think that Active Record as merely an entry point to the hey-i-have-to-save-that-thing concept is a good approach. Fowler’s definition is too tight and I advocate for an AR that is merely an opposite to the Data Mapper pattern (instead of having another class to do your ORM stuff do it on the class to be persisted).
By the way, Hibernate does not imposes or even suggest ARs, it works with both mappers and ARs.
Cheers
May I point out that in Fowler’s terminology, an Active Record by definition contains domain logic. If there’s no domain logic, it’s a Row Data Gateway. It may be unfortunate that Rails (and some semi-clones such as a few PHP frameworks) has been based on Active Record. Working in PHP, I’ve always preferred Data Mapper and I think Fowler has confused everyone by claming it’s more complex than Active Record. Its inherent complexity is only marginally greater. Active Record violates the Single-Responsibility Principle for no good reason.
Yes, ActiveRecord bends my head trying to make it fit into a clean mental model of an application. Rails uses a MVC architecture, Views and Controllers are for dealing with creating the user interface, so that only leaves a Model component for everything else, which is why you often hear Rails developers say, “Fat models are good”.
If you want to see an example of framework that cleanly makes the distinction between “data components” and components that are “purely behavioural but explicitly specify what types of data sets they can add behaviour too”, then take a look at Grok.
Grok also gives you clean distinctions between objects that can create new objects and objects that are just there to hold data. Grok by default uses the Zope Object Database (ZODB), a transparent object store, so you can sub-class your Schema classes to your hearts content, organize your objects hierarchically, and not have to think twice about polymorhpic associations and single-table inheritance and ORMs and all that junk.
Bob,
This is definitely an interesting article and I think you are very right to say that there’s a lot of confusion about this subject.
“Stand alone” Active Record is very good for simple scenarios and a lot of ORM tools are doing a great job providing/enabling them. In other cases however, the active records should serve as a lower level layer for building a business layer on top of. But, as stated in some comments, developers tend to cling on the AR paradigm to much when starting the BL. Like Andy P, I’d also like to see so a follow up post on this.
There is certainly a lot of confusion on this aspect. I think the confusion comes from the fact that objects are somewhat married to their knowledge of persistence.
You have persistence concerns, and object concerns, and you want to separate them away in as clean a fashion as possible.
If you ever want to read about .NET specifics on this I wrote up a rough blog post here: http://www.acceptedeclectic.com/2007/11/architecture-confusion-with-orm.html
just my take on it, though.
I agree with everything here except the conclusion. You want to make the application emune to data (type) changes, but what if he application itself is data centric?
Immunity to polymorphic changes in behavior based on a common encapsulated data set is the OO way, but most CRUD applications have little behavior in my experience. They are all about the retrieval, presentation and storage of data (state). Beyond this there is no (or very little) behavior at all.
LINQ is interesting. A relational database record is in fact an hashmap (set of name, value pairs), that has no behavior. Relational database applications are therefore data centric.
Coming back to the open/closed principle, I cannot see how you could achieve immunity to data (type) changes in a data centric application. So why not forget objects and data encapsulation, and just use data records (hashmaps) instead? A CRUD application is all about data structures and different data representations (database records, UI models and views). Changing the data changes everything.
Perhaps Objects just don’t fit here and a functional approach like LINQ is a more natural fit?
(BTW. You’ve got yourself to blame for my “back to basics” thinking, I went on one of your OO Design courses many years ago, and the thing I took away is your idea of tying everything back to first principles. Thanks Uncle Bob :^))
Paul.
Can you think of a single object you have ever used that didn’t expose its fields, either directly or via properties?
Likewise, can you think of any data structure that doesn’t have functions or methods that work against it?
You say: “In languages like C++ and C# the struct keyword is used to describe a data structure with public fields. If there are any methods, they are typically navigational. They don’t contain business rules.”
Actually, the only difference in C++ between a struct and a class is the default visibility of the members.
and the default visibility of inheritance. Structs assume public inheritance, and classes assume private. (Some folks have argued that C++ classes should default to public inheritance and private variables, whereas C++ structs should default to private inheritance and public variables!)
Can you think of a single object you have ever used that didn’t expose its fields, either directly or via properties?
Sure. Take the example of a geometric line. The variables held by this line are P1 and P2, the two points that define the line. These points never appear at the interface other than in the constructor, because they are utterly irrelevant to the mathematics of the line. The kinds of questions we ask of a line never require an answer related to P1 or P2.
Likewise, can you think of any data structure that doesn’t have functions or methods that work against it?
Generally a data structure will have some functions that operate on it. However, in many systems you will find functions that operate on more than one data structure at a time. These are not easily translated into methods of one or another of the data structures.
but what if he application itself is data centric?
I’m not sure I know what a “data centric” application is. Applications always operate on data, and data is always operated upon by applications. Applications are collections of behaviors that operate on data.
Perhaps you are thinking of CRUD applications. But CRUD is still a set of behaviors.
In any case, I don’t want to make applications immune from type changes so much as I want to make application immune from the most likely kinds of changes. If functions are more likely to change than data types, then a procedural style may be more appropriate. If data types are more likely to change then an OO style may be more appropriate.
To my eye the main (though far from only) reasons you want to expose state (even through properties) are for display or persistence.
As you say using Active Record objects in a DB mapping layer allows flexibility in your object design. Having said that many ORMs allow mapping to fields anyway and I’ve found they map inheritance/composition quite nicely too so I can usually create the domain model I want without having the extra layer.
Equally when displaying your domain model to the user you need some way of exposing the data. Some people handle this by exposing presentation DTO’s (or a proper Fowler Presentation Model). This does provide a lot of flexibility, especially if you use mapping, but ultimately your domain object still need to expose their state. The thruth is I’m not sure that there is much you can do about this unless you get your domain objects involved in their own presentation.
Anyway I agree with some of the earlier comments, to me Active Record is somewhat unappealing and I usually prefer to go for a more DDD focussed approach.
In a nutshell, I see nearly every common business application as a combination of at least two separate functions: Business and Maintenance. Active Record is good for maintenance (e.g. I need to update a person’s name). Objects (more specifically. Business objects) are good for business (e.g. I need to calculate projected sales).
I will also add that in my world I stress that business objects are immutable where active records clearly are not.
I have blogged about this very topic, if you are interested: http://swcses.eponym.com/blog/_archives/2007/2/26/2766594.html
Hi Bob,
In any case, I don’t want to make applications immune from type changes so much as I want to make application immune from the most likely kinds of changes.
I agree. I think this is the point. So back to CRUD. Have you ever tried adding another column to a database table in a CRUD application? The change ripples all the way through to the html view. No immunity to type change here at all.
It seems to me that the behavior is the immutable thing (CRUD) and the data types are the things that change all the time. Thats why making behavior (functions) the central abstractions is perhaps a better bet, and why I think LINQ is interesting.
Perhaps with our current focus on ORM, we’ve been barking up the wrong tree?
Paul.
Hello Bob. I found this blog from Paul Beckford’s blog. I posted a comment there since this is an interesting discussion.
And, reading your blog, the first thing that draws my attention is your definition of Active Record, as a way to map Database Rows to Objects. Looking at it in that way, I may say AR fails since, as you mention, OO is closed.
But I prefer to look at it with a change of direction: It may allow the objects to wrap behavior around data. Reading the other comments, I see people trying to work with a domain concept (call it person) as an object/record mix, and there the new and destroy and find methods don’t fit as a person behavior!. Of course! But those methods do fit as data behaviors!.
So, what is the solution? A person is an object that lives in the problem domain and is used to find a solution. That whole model may need persistence, a database. That is another model underneath, and totally “disconnectedâ€. So, person should not be performing data processing behavior, not should it be confused with a record! Person should request information to an information provider object, and that one should be calling the database world to request data processing. Complete separation.
Now, you can change the data model without impacting the business logic solution domain!.
How do you process data? Stored procedures is one option. But if you want to have a solution in one language, then native queries may be the answer. And those include AR and LinQ, for instance.
I will be blogging about this some more, it is very interesting,
William Martinez Pomares.
blog.acoscomp.comHello Bob. I found this blog from Paul Beckford’s blog. I posted a comment there since this is an interesting discussion.
And, reading your blog, the first thing that draws my attention is your definition of Active Record, as a way to map Database Rows to Objects. Looking at it in that way, I may say AR fails since, as you mention, OO is closed.
But I prefer to look at it with a change of direction: It may allow the objects to wrap behavior around data. Reading the other comments, I see people trying to work with a domain concept (call it person) as an object/record mix, and there the new and destroy and find methods don’t fit as a person behavior!. Of course! But those methods do fit as data behaviors.
So, what is the solution? A person is an object that lives in the problem domain and is used to find a solution. That whole model may need persistence, a database. That is another model underneath, and totally “disconnectedâ€. So, person should not be performing data processing behavior, not should it be confused with a record! Person should request information to an information provider object, and that one should be calling the database world to request data processing. Complete separation.
Now, you can change the data model without impacting the business logic solution domain!.
How do you process data? Stored procedures is one option. But if you want to have a solution in one language, then native queries may be the answer. And those include AR and LinQ, for instance.
I will be blogging about this some more, it is very interesting,
William Martinez Pomares.
blog.acoscomp.comhey
You can read my view on Data Structures and Encapsulaed Objects here: http://morten.lyhr.dk/2008/10/data-structures-vs-encapsulation.html
Hi Bob,
I’m enjoying reading Clean Code. I’m learning a lot from it – thank you for this fantastic resource.
Would you be willing to take some time to provide an example to show a way on how to use Objects and Active Records together?
This is the only part of the book I’m having trouble working out what an implementation might look like.
Kindest regards,
Eliot
Hello Bob,
Very interesting subject, I’m personally not a fan of frameworks using AR for many reason, I think these concepts become popular because: a) Many developers have come to consider an application a set of CRUD pages, b) Frameworks have as you mention messed up concepts and because they facilitate work and make programming faster (for simple apps at least) developers accepted it c) Not every developer have the knowledge and perspective
Perhaps I’m lucky or unlucky but most applications we develop have hundreds to thousands of lines of pure business rules.
I have myself made a PHP framework (MVC) and we currently use this concept:
Model. This is an independent object (no inheritance forced), it can just facade a complex object model to expose the methods the controller and the view need, it can get/access any of the other objects that makes the model and any DAO’s to get data. For CRUD applications (generator makes them): You can make it child of CRUD_model and declare a DAO type (Crud_model will just pass the calls to DAO in this case but it makes the difference clear, new methods with BR are added to the Model, new methods for data access are placed in the DAO)
DAO. The Data Access Object are in charge of all data operations, save, update, find, get, delete, exist, etc; it’s like the manager, person_DAO, then a person doesn’t destroy itself, even better doesn’t find itself!
VO. Value Objects are simple data structures that represent a record, DAO gets and returns DAO’s for most actions $person_DAO->save($person_VO);
VO properties normally match DB fieldnames, but they can be mapped in case of change, i.e. DB.I_NAME ~ VO->EmployeeName
DAL. DAO runs on top of a DAL to access many DB’s
Don’t know if this is better, but I think it keeps it clean in between an object with BR, the manager and the data structure/record
Best regards,
Itzco
Hi I crafted another ORM layer that uses the anemic domain model. As I see it the Anemic Domain Model is a perfect tool to communicate with the database. In a sense the Anemic Domain Model serves the world of OO by providing a robust and very uniform object centric interface to the database. I agree however that these objects should not (always) be used for the business layer (I mean the layer that contains classes that express specific behaviours). Personally I favour wrapping the beans in complex models that use these beans and other repository tools to facilitate database interaction. So in the end, classes that ‘talk’ to these models will have no awareness of the database structures.
I think that this pattern is often poorly understood and educated, I find myself having trouble to detect the smell properly; if you look closely at projects the symptoms can be spotted but that’s hard. When I see helperEmployee, EmployeeController or EmployeeManager I see anemic traits. What do you think about this?
And.. if you are using an MVC architecture; does this mean that all classes that are not part of the C or V layer are models? What about mediators, facades etc? How should one classify these structures. The exhibit behaviour; but no data? Are they also non-oo?
Another frustrating issue is the single responsibility principle. Many Anemic Domain advocates (including me sometime ago… sorry uncle Bob ;) ) claim (and they are right about that I think) the Anemic Domain Model implements SRP very well. by the way my own ORM is RedBean: http://www.redbeanphp.com—its a virtual orm layer; meaning it designs its own database based on your code.
I see no mention of opaque data objects – something you can do in C using typedef and struct, where in a header file (the API):
typedef struct my_opaque_data my_opaque_data;
and the you define the struct in the implementation. This is common practice, and the methods typically use a naming convention such as:
my_opaque_data* my_opaque_data_new(void); void my_opaque_data_free(my_opaque_data*);
Tell me which exposes more in the API, this or C++ classes?
Admiring the time and effort you put into your blog and detailed information you offer!
The web client and the window and the java script causes problem for some. Anyway as everything has some sort of disadvantages this software may also have them but the point we have to note here is that how many people are
am preparing the manuscript for production
a so
I see no mention of opaque data objects – something you can do in C using typedef and struct, where in a header file (the API):
typedef struct my_opaque_data my_opaque_data;
and the you define the struct in the implementation. This is common practice, and the methods typically use a naming convention such as: cheap VPS my_opaque_data* my_opaque_data_new(void); void my_opaque_data_free(my_opaque_data*);
Tell me which exposes more in the API, this or C++ classes?
Date production is always harder then objective crystal potpourri | scented crystals | scented rocks
Keep in mind that although we typically know what the effects of two or more drugs have the mechanism
tnaks for sharing and informations..
I know it’s old post but really interesting to read
Active Record‘s main contribution to the pattern is to relieve the original of two stunting problems: lack of associations and inheritance. By adding a simple domain language-like set of macros to describe the former and integrating the Single Table Inheritance pattern for the latter, Active Record narrows the gap of functionality between the data mapper and active record approach.
Awesome topic.Thanks for sharing!!
Thank you for share very nice informations. Your web is greatI am impressed by the information that you have on this blog. It shows how well you understand this subject. Bookmarked this page, will come back for more. You, my friend, ROCK! I found just the information I already searched everywhere and just couldn’t find. What a perfect site. Like this website your website is one of my new favs.I like this site presented and it has given me some sort of commitment to succeed for some reason, so thank you
However RSpec uses an alternative syntax that reads more like a specification than like a test. Let me show you what I mean.
I don’t know much about it. So, I want to study. When I come to here, I think I am in the right place. the web gives me a lot of infomation, it is very informative. I think lots of people can learn much here. I will come to here again. Thanks.
If you mean to find great shoes for your children puma speed trainers also provides a mixture of finicky and affordable shoes for them. There are a lot of choices, it is up ring call,Ugg Boots, after by people that indigence an incredible quantity of column. This will make the customers happier. If you are often tangled in Singapore womens puma future cat shoes sale at Sainte Marie that could enhance operational efficiency, range visibility and turnaround time,” said Desmond Chan, managing boss, South Asia, Menlo Worldwide Logistics. “Our multi-client facility in Boon Lay Way provides puma trainers with different flag. puma uk’s youngest targets are toddlers. The puma for sale shoes are incredibly affordable, yet they still hold the grace. Wearing comfortable shoes will help children exploit better.
As the Apple iphone 4 bumper is taken off the marke, will white iphone 4 available soon?
With the right tool, you can easily burn mp4 to dvd and itunes to dvd. Also, you can use drm removal tool to remove drm protection from itunes, zune, amazon legally. wmv to dvd, mov to dvd, mp4 to dvd, itunes to dvd
So objects are not immune to the addition of new functions.
Thanks for shareing! I agree with you. The artical improve me so much! I will come here frequently. iPad to Mac Transfer lets you transfer music, movie, photo, ePub, PDF, Audiobook, Podcast and TV Show from iPad to Mac or iPad to iTunes.
I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad PDF Transfer for Mac can help you transfer ebooks in PDF format from ipad to mac/iTunes.
The problem is that Active Records are data structures.
I want the application oriented around objects that expose behavior and hide data. I generally want the application immune to type changes; and I want to structure the application so that new features can be added by adding new types.
Anyway as everything has some sort of disadvantages this software may also have them but the point we have to note here is that how many people are.
Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad PDF Transfer for Mac can help you transfer ebooks in PDF format from ipad to mac/iTunes.
have them but the point we have to note here is that how many people are.
This article was Very helpful. Actually, Featured Products I am fond of reading online punjabi news Travel Pots &Mugs. Thanks for writing such a complete Sports Bottles. thank you for sharing. Double wall car mug
love the ideas presented!
Buy $10 Replica Designer Sunglasses with 3-day FREE SHIPPING
We are the professional shirts manufacturer, shirts supplier, shirts factory, custom shirts.
The artical improve me so much! I will come here frequently. iPad to Mac Transfer lets you transfer music, movie, photo, ePub, PDF, Audiobook, Podcast and TV Show from iPad to Mac or iPad to iTunes.
Thanks for this article.I like its.As to me it’s good job.
Wow, nice post,there are many person searching about that now they will find enough resources by your post.Thank you for sharing to us.Please one more post about that..
I’d use a pure AR solution only if I’m very very sure that I’m dealing with a simple CRUD that won’t change in the future
nice post
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
Way to stay positive and stick with something you love!
Mr Coates coach purses is the longest U.S. market popular with one of the most successful leather brand. Mr Coates coach purses store represents the most admirable American fashion innovative style and traditional skills . Mr Coates coach bags have durable quality and exquisite technology, Conspicuous Coach Heels in the female consumers have good reputation. Welcome to our shop Elegant Coach Purses
fashion jewellery shop with
I attempted these beats by dr dre studio out in several genres thinking about which i listen to an eclectic mix Beats By Dr Dre. a washing cloth as well as the manual. Do not purchase any beats by dr dre solo purple products inside the internet unless you’re getting from an Authorized internet DealerBeats By Dre Just Solo. We are reliable provide good beats by dr dre pro black by reduced price.
Walk on street, you will find that there are so many Ed hardy stores and Ed hardy clothes selling well. Due to the unique design and vigorously promoting, Ed hardy clothing becomes more and more popular. Youcan find Ed hardy clothes or other Christian Audigier accessories on any Ed hardy stores online.
Good Information Very nice post.
Thank you for you article, and I learnt from it that you must be a kind-hearted person. As a wife-to-be who is going to have this San Patrick wedding dress on I am grateful to you for your introduction of the Demetrios dress. I am looking forward to better articles from you,introducing to us various styles of Maggie Sottero dress, and I will surely introduce your articles to my friends, especially brides-to bewho are in want of a Mori Lee dress. Your articles will help them a lot!
This article is really helpful and wonderful and would be better if more introductions of the Demetrios wedding dress are available.
This article is really helpful and wonderful and would be better if more introductions of the Alfred Angelo wedding dress are available.
Hello guys,
please see my link uk exporters this is export import related.
thanks
Hello !
I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad PDF Transfer for Mac can help you transfer ebooks in PDF format from ipad to mac/iTunes.
online import export agent online sellers
North Face Apex Bionic Kvinder Jakker
plus thighs and leg,the north face
plus improved during losing fat laden calories might move barefoot in the inclusion. In that case keep account.December 2012 will be to can comecanada goose jakke, lots of believers live 2012 is just about the most important issue with discourse. mbt internet profit internationally renowned students will be guessing devastating incidents which is nearly anything. Let’ vertisements evaluate ways to live 2012canada goose , principally around the best way far better create you actually for any predictable.
Thanks for the post. i like it.
global importers directory | global exporters directory
Amazon Scarpe Ugg , di gran lunga i posti più biologicamente distinte sulla terra, l’Amazzonia può essere descritto come vero e proprio paradiso per gli amanti della vera natura che apprezzeranno questa miriade di programmi per il bird-spotting e persino animali revisione, come molto bene l’acquisizione di perso in mezzo a lussureggianti insieme esotici rainforest.The amazon Il mercato online copre il pezzo gigantesco cavallo di proprietà relative ai diversi Stati americani Latina, con un bel paio di destinazioni sorprendenti per iniziare avventurosa explorations.Read Amazon che guida al meglio i gateway in giungla, in un viaggio associata a una vita, mentre nel più grande al mondo acquire.About dimensioni protetto il 33% del Perù è incluso nella Ebay, con non uno ma due luoghi importanti dal punto in cui siete in grado di iniziare un viaggio: Iquitos di non menzione Maldonado.Puerto Puerto Maldonado, nel sud una parte naturale del Perù è in prossimità di alcuni parchi nazionali straordinaria carica di incredibilmente caricato e distinte wildlife.With queste, la Riserva Nazionale Tambopata e poi il Parco Manu indigeni fornire migliori opportunità di business per invidia del bosco e anche la sua popolazione particolare peculiare.
Stivali Ugg , Ones proprio telefonino cellulare è praticamente tutta la parte di voi come le orecchie su entrambi i lati della testa rispettive, ma chiunque ascoltare “Greensleeves” (soprannome che significa molte volte in un giorno base sarai pronto a massacrare chiunque solleva Enrico VIII nella vostra risoluzione presence.You il telefono cellulare in modo automatico che non si preoccupano di apparire e fermarsi e vedere chi sta chiamando, e si prevede di evitare di raccogliere tutte le chiamate in tua madre in questi giorni, perché hai a spiegare perché “studiare” necessita di musica ad alto volume con il ronzio delle diverse conversazioni in background.How si può aggiungere un po ‘d’incoraggiamento per le melodie tradizionali o-brivido-appena squilla suonerie che affliggono il tuo cellulare cellulari per tutta la sera? Come hai potuto vedere solo una suoneria insieme a conoscere intuitivamente chi telefonare, senza dover nemmeno spendere il vostro telefono cellulare dalla tasca? Abbinando i tuoi buoni amici con la maggior parte dei componenti animalesco o semplicemente naturalistico con suonerie con animali, Suonerie per animali, Cercare Suonerie, così come suonerie Design! Chi è il tuo demenziale solo all’interno di ogni famiglia con cerchia di amici? Sappiamo tutti 1 e due! Poi che dire di alcune suonerie Frog? Chi è il tuo lupo solitario nella confezione? Forse lei o lui sarebbe più essere elencati da alcuni Lupo Suonerie scaltro! Chiunque in nome della quale è normalmente Donald così come Howard ha bisogno solo per ottenere uno degli individui Anatra Suonerie-la battuta sarà anche impagabile! Avere un certificato “gattara” tra il raggio? Sfoglia via Suonerie animali prima di individuare qualsiasi felino miagola che meglio rappresenta la donna.
You had 42 blacks that ran on the Republican ticket this Cycle, 14 made of them made it to the general election and two of us made it to the House of Representatives. So I think that there is a new movement that needs to have a voice in the Congressional Black Caucus.
Ugg Italia , chi non potrebbe fare glitch? Hammurapi con Babilonia? Thutmosis 3 di Egitto? Hattushilis III del vostro impero ittita? Sennacherib di Assiria? Shorkaror con l’Etiopia (Kush)? Cambise con l’Iran? Alessandro il bello della Macedonia? Ottaviano Augusto con Roma? Harun Rashid zione del califfato abbaside? Solimano il Magnifico del vostro impero ottomano? Donne fatte marze; e ciascuno di loro erano molto good.Siad successo Barre chiaramente lui diretto al tuo picco collegata con i paesi dell’Africa statista del ventesimo secolo; La storia lo nomina come il più grande Statista equipaggiamento fotografico il 20 100 anni, vi devo informare a ora che, quando lo storico, comunico il realistico, storia vera che rende un sigillo irrevocabile di approvazione – non del falso, massonici pseudo-storia che attualmente ha penetrato le pubblicazioni del globo e dei media solo che dovrebbe essere presto diluito con evaporato, e la prossima obliterazione del corpo reale sul enterprise.But satanica che l’intento dell’articolo è né essere un elogio funebre né a servire per essere un elogio, oltre ad un encomio. “nuovo mondo” Hysteria ordine a fianco il presidente Siad Barre maggio e comunque finiscono interessante esaminare motivo per cui il popolare regime Buy World, con le sue marionette collegate con i diplomatici, uomini di stato più accademico, utilizzando tutto un romanzo poco raccomandabili, e utilizzando tutti i siti web di parte della nazione, come Wikipedia, descrivere Siad Barre per un maestro militare, e incessantemente lo scopo di rappresentare il suo lavoro grande nel modo più indegno
Ugg Italia , chi non potrebbe fare glitch? Hammurapi con Babilonia? Thutmosis 3 di Egitto? Hattushilis III del vostro impero ittita? Sennacherib di Assiria? Shorkaror con l’Etiopia (Kush)? Cambise con l’Iran? Alessandro il bello della Macedonia? Ottaviano Augusto con Roma? Harun Rashid zione del califfato abbaside? Solimano il Magnifico del vostro impero ottomano? Donne fatte marze; e ciascuno di loro erano molto good.Siad successo Barre chiaramente lui diretto al tuo picco collegata con i paesi dell’Africa statista del ventesimo secolo; La storia lo nomina come il più grande Statista equipaggiamento fotografico il 20 100 anni, vi devo informare a ora che, quando lo storico, comunico il realistico, storia vera che rende un sigillo irrevocabile di approvazione – non del falso, massonici pseudo-storia che attualmente ha penetrato le pubblicazioni del globo e dei media solo che dovrebbe essere presto diluito con evaporato, e la prossima obliterazione del corpo reale sul enterprise.But satanica che l’intento dell’articolo è né essere un elogio funebre né a servire per essere un elogio, oltre ad un encomio. “nuovo mondo” Hysteria ordine a fianco il presidente Siad Barre maggio e comunque finiscono interessante esaminare motivo per cui il popolare regime Buy World, con le sue marionette collegate con i diplomatici, uomini di stato più accademico, utilizzando tutto un romanzo poco raccomandabili, e utilizzando tutti i siti web di parte della nazione, come Wikipedia, descrivere Siad Barre per un maestro militare, e incessantemente lo scopo di rappresentare il suo lavoro grande nel modo più indegno
Ugg Italia , chi non potrebbe fare glitch? Hammurapi con Babilonia? Thutmosis 3 di Egitto? Hattushilis III del vostro impero ittita? Sennacherib di Assiria? Shorkaror con l’Etiopia (Kush)? Cambise con l’Iran? Alessandro il bello della Macedonia? Ottaviano Augusto con Roma? Harun Rashid zione del califfato abbaside? Solimano il Magnifico del vostro impero ottomano? Donne fatte marze; e ciascuno di loro erano molto good.Siad successo Barre chiaramente lui diretto al tuo picco collegata con i paesi dell’Africa statista del ventesimo secolo; La storia lo nomina come il più grande Statista equipaggiamento fotografico il 20 100 anni, vi devo informare a ora che, quando lo storico, comunico il realistico, storia vera che rende un sigillo irrevocabile di approvazione – non del falso, massonici pseudo-storia che attualmente ha penetrato le pubblicazioni del globo e dei media solo che dovrebbe essere presto diluito con evaporato, e la prossima obliterazione del corpo reale sul enterprise.But satanica che l’intento dell’articolo è né essere un elogio funebre né a servire per essere un elogio, oltre ad un encomio. “nuovo mondo” Hysteria ordine a fianco il presidente Siad Barre maggio e comunque finiscono interessante esaminare motivo per cui il popolare regime Buy World, con le sue marionette collegate con i diplomatici, uomini di stato più accademico, utilizzando tutto un romanzo poco raccomandabili, e utilizzando tutti i siti web di parte della nazione, come Wikipedia, descrivere Siad Barre per un maestro militare, e incessantemente lo scopo di rappresentare il suo lavoro grande nel modo più indegno
good post, i think so.Thank you!
Om canada goose jakke spørgsmål vedrørende fødevaresikkerhed, canada goose Gruppen af otte forventes canada goose outlet at lancere “Aquila fødevarer belstaff outlet security initiative”, vil være os $ 10-15 milliarderi belstaff støtte begået for landbrugs udvikling i fattigere Canada Goose Ungdom Freestyle lande.Med hensyn til finansforordningen forventes gruppen af otte ledere at være “Lecce rammen” Hot Salg på grundlag af vedtagelsen canada goose jakke af en politikfil, cross-domæne Canada Goose Banff Parka for at styrke tilsynet med banker, institutioner og virksomhedsledelse, og I am legend og har Hot Salg for nylig udgivet selvmord.I dag, efteråret Canada Goose Handsker på ny hylden, ikke kun mode, men vil holde dig tilsluttet på legender af læder.
real a good post , i am very like it , will come back again
UGG Classic Patent Paisley 5852 , gibt es einen einfachen unteren Professor an die Universität Schüler-Verhältnis für die Gemeinschaft Hochschulen mit der Absicht, die Professoren Zeit, um mit den Bedürfnissen der individuals.Another viel ernten einige Vorteile haben kann, ist das auch erlauben Sie mir zu erklären, gehen Sie zu denen Sie vier yr Grad nur nach Abschluss einer Gemeinschaft Fakultät Ausbildung können Sie sich, dass ein Individuum die Ertragskraft Möglichkeit deutlich über Leute, die nicht haben, werden bei kleinsten einer zweijährigen Sekundarstufe education.Research ebenso zeigt die Tatsache, dass Studenten, die einen fabelhaften Zwei-Jahres-Level-Programm in einem Community College abgeschlossen eher fertig sind und einen Vier-Jahres verbessert Diplom als alle Studenten so, die eigenen pädagogischen Erfahrung beginnen bei einer Vier-Jahres-collage.There können ein paar Probleme, die durch eine Gemeinschaft Fakultät Bildung assoziiert begleitet werden könnten und sollten Sie beachten, von denen zu nehmen, damit sie nicht in eine nicht aktivieren Problem für you.First aus allen neigen einige Universitäten nicht zu viele Kurse auf dem Community College Tier als Transfer-Credits zu akzeptieren.
The professional design make you foot more comfortable. Even more tantalizing,this pattern make your legs look as long as you can,it will make you looked more attractive.Moveover,it has reasonable price.If you are a popular woman,do not miss it.
Technical details of Christian Louboutin Velours Scrunch Suede Boots Coffee:
Fashion, delicate, luxurious Christian louboutins shoes on sale, one of its series is Christian Louboutin Tall Boots, is urbanism collocation. This Christian louboutins shoes design makes people new and refreshing. Red soles shoes is personality, your charm will be wonderful performance.
India Export Import Agents Success Stories: If you are looking for export of Indian imports, import export companies of goods from anywhere in the world, is a lucrative business. To be clear, there are success stories from around the world of the Indian import and export, import and export agents in Asia, USA, Australia, Europe in fact, the name of the country and is an example of success, but before entering blind in this business, you should know what to do and how to do it.
good news dude. keep it up.
bengal cats
Very nice, as you know Gold is a semi-precious way of chalcedony which has modifying instantly organizations of color, most usually darker, red, gentle, and dark-colored. It is dark-colored when cut and enhanced successfully, very significant also.
real a good post , i am very like it , will come back again
Active Record vs Objects 96 hoo,good article!!I like the post!54
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
Fashion trends change on daily basis. To keep up with the fashion industry Christian Louboutin can be quite a daunting task. Women have so many choices in front of them Christian Louboutin studded flat boots that it is difficult to choose from. Changing your wardrobe each day is not Christian Louboutin slingback peep toe feasible and not possibly unless you have extra money to spend. Knee high Christian Louboutin shop boots is one piece of footwear that helps you look fashionably dressed and servers the purpose to give you a new looks for every occasion.
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.
With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.
i am really satisfied the great info. it is a very nice blog.i am agree with you for this post
This is a great post and thank you for sharing this nice blog
I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities attract us.
Intertech Machinery Inc.
With more than 25 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
Main Products:
Injection Mold, Silicone Molding, Rubber Mold, Silicone molding, PC High-Gloss Plastic Mold, Die Casting Mold, Silicone Mold, Silicone Rubber Mold, Liquid Silicone Rubber , Cosmetic Packaging Mold, Medical Products Mold, Engineering Plastic Molds, Home Appliances Mold, etc…