Are Code Generated POCOs Really POCO?

Monday, July 5, 2010

We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it's caught on very nicely.

- from MF’s definition of POJO

The .NET equivalent to a POJO is a POCO (plain old CLR object). POCO is a popular term in .NET development today, having caught the momentum POJOs started generating 10 years ago. This isn’t because .NET is 10 years behind the curve. POJO developers were revolting against the tyranny of oppressive  frameworks during a time when .NET developers were resetting from COM+ to managed code. The  COM+ / WinDNA locomotive was headed in the same tyrannical direction when .NET derailed the train into relative simplicity.

But, I digress.

When I ask developers these days what POCO/POJO means to them I get consistent answers. Stuff like:

  • A POCO doesn’t need to inherit from a framework base class or interface.
  • A POCO isn’t restricted in the data types or relationships it exposes.
  • A POCO is relatively free of infrastructure concerns like persistence.

All these are good rules to define POCO. But why do these rules exist?

Java developers wanted POJOs because they wanted to own the code. The “plain” part is a side effect. They wanted to build object models without the restrictions imposed by a framework. They wanted the freedom to establish hierarchies and relationships. They wanted to pick the data types most suitable for a problem instead of using the data types required by infrastructure. I believe the true spirit of POJO/POCO-ness is only achieved when a developer cares deeply about the POCO classes. Like a gardener who cares about seedlings – the developer wants to grow the classes with a hands-on approach.

 

Child Tending Broken Baby Seedling by Pink Sherbet Photography.

 

A generated POCO is an artifact a tool spits out after deriving information from another source -  like a database schema. In most cases this is not a one time generation used to bootstrap a project. Instead, the code generator owns the POCO classes. Code generation dilutes the spirit of POCO.

Perhaps we need a new term: POGO – plain old generated object.

What do you think?


Comments
gravatar Michael Foltz Monday, July 5, 2010
I love it! Now all we need is some clever analogy that evokes the image of a little kid bounding down the sidewalk with a pogo stick...
John Rusk Tuesday, July 6, 2010
I agree, there does seem to be a difference between a POCO and a POGO -- except perhaps for the simplest variants of POGOs. (E.g. don't generate the code to do property change notifications etc, so that you end up with a POGO that looks like a POCO you may have written yourself). Even then you have the difference in ownership of the code, which I think is very significant, as you suggest.

I think one of the challenges is that, these days, we expect relatively rich behaviour (such as property change notifications, bi-directional relationship maintenance etc) and that's harder to get in the kind of POCO one may comfortably write by hand.

One solution is dynamically-generated subclasses. I also tried out another approach here, which gets the rich behaviour without dynamic subclasses: http://close2poco.codeplex.com/ This approach meets your goal of letting the developer own the code (but unfortunately it is out-of-date, being based on LINQ to SQL). Nevertheless, I found it an interesting exercise in getting my head around what POCO should mean.
gravatar Jauco Tuesday, July 6, 2010
I like it! Though perhaps POGO sounds too innocent... especially since a POGO defers even more responsibility to a framework than a non-POCO does.

How about "Object that Must be Generated"? (OMG) :-P
gravatar Thomas Eyde Tuesday, July 6, 2010
Excellent put! Since EF came out with the POCO template, I have thought of it as an abomination. That you can't use POCO and code generation in the same sentence.

But I haven't been able to articulate why, it's just a feeling it is plain wrong combined with the feeling that code generation is so 1990.

Ownership is a subtle, but important aspect of POCO. However, I never thought of it until now.
Frans Bouma Tuesday, July 6, 2010
Focusing on 'owning' the code of entity classes is stupid. What people should focus on instead is what that class represents: WHY is it the way it is. The answer is very simple really: it is a projection result of an abstract definition. I.o.w.: the class isn't the source (pun intended) of what e.g. the entity 'Customer' means, but just a projection of the 'Customer' definition so we as developers can work with it.

To create such a projection, one can type it in by hand, or generate it from the definition in some digital form. _how_ the class is created is totally irrelevant. If someone thinks it IS relevant, please re-think why you wrote the entity class the way you wrote it, manually. Generating that class is simply automated typing: let a machine do the manual labor.

Some people think that by letting a machine do the dumb cumbersome work of writing a lot of classes with property definitions / member definitions and the mapping files a bad thing. I really don't think these people truly understand what on earth they're doing. And neither do I think their bosses know what the heck these people are doing all day.

In the manual of llblgen pro v3 (which can generate poco classes for you for nhibernate or ef for example, or generate a document which describes what you should write manually if you want to) I described the theory behind the process: http://is.gd/dh7zS [llblgen.com]
gravatar Justin Etheredge Tuesday, July 6, 2010
To me, the whole idea of a POCO, and why you would want one in the first place, is to make things easily editable. If I didn't need to read it, and didn't want to edit it, then why the hell would I care whether or not it was a POCO?

If we think about why people fight so hard for POCOs, it is to keep things clean and simple and allow for developers to edit them. As Frans said, having a machine generate these files might not necessarily be a bad thing, but if we assume that a machine is going to be generating the file over and over, then it leads us down a path where we have less and less control over that entity. Take "buddy classes" and "partial classes" as an example... they are a solution to a problem that wouldn't exist if people didn't depend on code generation so much.
gravatar Thomas Eyde Tuesday, July 6, 2010
What I don't understand about code generation, except that I have been bitten in the past by unfortunate choice of tools, is how effective they really are compared to other methods.

Code generation doesn't work by magic, the tool must be configured. Now the source for our code is further away. So when I discover a bug, I first have to understand how it got generated, then I have to understand how to reconfigure it correctly.

That seems magnitudes harder to me than just fix the code.

Tools like ReSharper, CodeRush and other takes away much of the manual labour. How does that compare to code generation?

With a good ORM and conventional coding, I know NHibernate with Fluent NHibernate can do that, all persistence logic is taken care of. All we have to do is writing our business entities.

I guess, and it's only guessing, that a setup like that is a decent competitor to code generation.
gravatar WilliamH Tuesday, July 6, 2010
What I don’t understand is there are actually people out there that are so anal they actually care about things like this? Really, code generators owning the code....

As Jack Nicholson (aka the Joker) in 1989’s Batman said it perfectly "This town needs an enima", just substitute "town" for .net community.
Frans Bouma Tuesday, July 6, 2010
@Justin:
"if we assume that a machine is going to be generating the file over and over, then it leads us down a path where we have less and less control over that entity."

Do you have evidence to back that up or do you just think it's true because everybody you know who's cool says it too?

First of all, the class != the entity and the class != the entity definition. It's a definition for a container which gives meaning to an entity instance (which is the data, in case you're wondering, not an object) so the data can be seen as a physical instance of an abstract entity definition.

Really, if you want to write entity classes by hand because your hand-written code is closer to achieving that, by all means do so, but frankly, I don't see the point in investing hours after hours of manual labor to achieve what a machine can achieve in a couple of seconds.

And you don't lose control at all. Simply because the class is a projection of a definition. So changing the definition is all it takes.
Frans Bouma Tuesday, July 6, 2010
@Thomas Eyde
You bitch about code generation, yet you think that FluentNHibernate is great. I think FluentNHibernate is ok, but please consider that it generates code as well, namely the XML you didn't want to type by hand.

It doesn't matter which machine you use to generate the code, as long as you don't claim that hand-written code is so much better. You see, it really is a lot slower to write code by hand, which can be generated from a definition, the SAME definition you use in your head to write the class manually.

And generating it has an advantage: the definition isn't in someone's head. It's in the meta-data of the code generator, so I can use that meta-data to generate other stuff too, oh and create fancy pictures of models as well, so your client can understand what on earth you're doing and what you're talking about.

But, Thomas, I don't pay your paycheck, your clients do. So as long as they don't have a clue you're wasting many hours with writing stuff by hand which could be generated using an automated tool, you're good. Unless they find out your competition is less expensive due to the usage of more advanced tooling.

Because using hand-waving bullshit that code generation is really not that great doesn't help then.
gravatar Scott Allen Tuesday, July 6, 2010
@Frans - I don't have a problem with codegen. I just think it's odd I'm running into people who "want POCO" without really considering why. I think if you stick to the original intent of POJO it's because you do want to write classes by hand (perhaps a test-first approach). I'm wondering how many projects generating POCOs could be switched into generating BLOATOs and never even realize something changed.
gravatar Fred Morrison Tuesday, July 6, 2010
The POGO vs. POCO debate seems eerily similar to the old pure COBOL vs. Case-tool-generated COBOL debate in the 1970's. My oh my how little has changed in the generated vs. hand-crafted code debate in the past 35+ years. At least we're not still using punched cards.
gravatar Thomas Eyde Tuesday, July 6, 2010
@Frans, did I really deserve those hash words? I am sorry if you take my words as a personal, negative criticism. That was not my intention.

However, I have had real, negative experience with code generation in the past. Bad choice of tooling, possibly, but nevertheless that tool did the opposite of saving time and money.

It's pretty obvious that a code generator does the work in seconds what hand coding would take days.

But somehow, the code generator has to be told how to generate the code. How long does that take?
gravatar WilliamH Tuesday, July 6, 2010
@Fred Morrison

Sounds like those same people of the 70's grew up and had kids who became developers also. We are doomed!!
Frans Bouma Wednesday, July 7, 2010
@Scott: I agree that there are a lot of people who want POCOs but have no idea why.

I can think of 1 reason why one would use POCO's, just one: when maintenance has to be performed on a code base and the code generator for some reason doesn't work anymore, you can still continue.

It's however a fallacy to think that because of that, code generation is thus bad. What people should focus on is what code generation really is: it's automated typing code: a machine does the typing for you. That's all. You press a button and you get code which is tested a lot of times already, compiles, works, and contains features you don't have to think about how to write them. A good code generator allows you to achieve that: by having an open system, where you can easily change, extend and append on the machine who generates the code for you.

@Thomas: the concept of generating code is misunderstood by a lot of people, often they spread FUD about code generation on forums, blogs etc. Of course there are code generators which are bad, similar to that the majority of developers out there is likely not very good with respect to writing code.

Code generation is really a simple process: you have meta-data which is the input, you have a template which consumes the meta-data and controls what's coming out and you have a little engine which executes the template. Writing a template isn't that hard: write what you want to generate by hand, then create a template to let a machine do it for you. Templates which are used by many people have the advantage that the code they produce is solid, well tested code which does what it should.

Because that's what's important: maintainability and bug free code.
gravatar PeterB Wednesday, July 7, 2010
I think it's a fine idea. And POGO already has a recognized avatar.

See http://en.wikipedia.org/wiki/Pogo_(comics)
gravatar Justin Etheredge Thursday, July 8, 2010
@Frans Oh, I have no evidence, just cool people. :-)

But really, I don't have a proof or anything if that is what you are looking for. But just look at what you are saying. If the generated class is a projection of a definition, then the definition is an abstraction of that class. If the "definition", or whatever tool you use to define the definition, doesn't support something you need in your projection... then the whole system stops working. If we operate on the assumption that we are going to be generating the classes over and over, then we are locking ourselves into the abstraction provided by the "definition". If however, the file is meant to be generated, and then tweaked... then I don't see any problem having a tool spit out code. I think that things such as scaffolding in Rails is a great example of that. It does the heavy lifting, but provides you with something that is meant to be tweaked and changed.

And let me reiterate, *I have no problem with codegen*. I just think that people are way to eager to use it generously, instead of solving problems in generic ways.

I feel like we have had this conversation before :-)
gravatar Bryan Watts Tuesday, July 13, 2010
Ah @Frans, it never ceases to amaze me how your abrasive style constantly gets in the way of making your point. You are an intelligent lion whose every rebuttal comes with a swipe of the claws.

I have always viewed code generation as a coarse solution to common functionality. If the code to produce requires such rote mechanics, why can't we express those concepts *without* all the automated typing? Why rely on a generator instead of concentrating on the ability to write more potent objects by hand? I am not saying code generation is not elegant; it is often quite sophisticated. It is a crutch, though, which when adopted as *the* right answer stunts the quest for simpler approaches.

I don't purport to know what those approaches might be, but I do know we will be less likely to discover them if we become content to let machines write the code we can't simplify enough to write ourselves.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!