My experience with POJOs

This post comes after I was asked to implement a new functionality, pretty easy by itself, but which was to be made inside a mess of objects, interfaces, and stuff like that. It was impossible to do within the current structure, so the choice was between making the nth ugly implementation to make things work or tear everything apart refactoring a good portion of the application, doing a lot of manual tests and coordinating with the other two teams who where using the framework my team was developing. I choose the latter.

If you're a developer in the Java world, you probably know about POJOs: the Plain Old Java Objects. Originally proposed by Fowler, this kind of pattern (if it can be called so) is characterised by a single class with multiple properties, and since we're in Java, this properties are private and each has its own getter and setter. Nothing more, nothing less. You probably have similar things in your favourite language of choice.

So far so good: everyone I know uses POJOs somewhere when developing a new application or functionality.

But here comes the bad. Imagine, for a moment, that you work for a company that's often rushing to meet deadlines. Imagine you have a very complex legacy system, which recently has been somehow hammered here and there to fit into a new and flashing REST API with Swagger and all the other bells and whistles. Maybe imagine it has to integrate various external services, and it's comprised of a back end component and a front end component. Optionally also imagine that said hypothetical company hires people which aren't exactly Java wizards and just a few in your team (or even entire organisation) are good developers. Such a company clearly doesn't exist since it wouldn't survive a lot of years in business, but for the sake of my argument let's imagine it exists.

This company would be in business in a particular domain, so it makes sense that different subsystems may handle very similar data. Often also the same data, but of course with different models. Everyone uses POJOs: let's say we're in finance, you may have “percent” and “percentage” inside “Fund” objects and “CoolFund” objects. Same thing, different name. “We have to create a new object, because we need the veryCoolProperty which your object lacks”.

Days pass. Project managers want features faster, while fixing bugs caused by previous fastness at the same time. Someone, sometime, somewhere has the brilliant idea, to speed things up, to make POJOs smarter and more complex, being able to do all kind of things: proxies are built to conform one subsystem POJO structure to that of another subsystem, various utility classes are made to map them back and forth, clever lambdas are used everywhere to make code more concise and do things with few and obscure lines of code.

Suddenly you have POJOs methods leveraged into interfaces of getter and setter (if you're lucky: otherwise someone threw a Builder pattern here and there and you have setters only deep under layers of software). Suddenly you have POJOs extending each other and no longer have a clear representation of what your data is, how it gets populated and how it's used.

While it's pretty obvious this are all anti patterns, I've seen this things happen, even done by developers better than me and even by me. Why? because we're humans I think. When clients and management pressure increases, your thoughts about patterns and anti patterns start to dissipate leaving room only to delivering that little functionality you have to do, meeting the two days deadline (or two hours).

How to prevent all this, given you can't change yourself, your colleagues or your company?

My takeaway: don't ever ever ever make POJOs complex. I'll be even more radical: don't use getters and setters and make fields public. If you have two different objects who differ only by a property, use the same object with the good old null value. Rule of thumb: only split POJOs if the number of unused fields in a subsystem is bigger than the number of used fields. But forget this rule if the number of used fields is > 5 or they are important fields.

This way extensions and interfaces make even less sense and people will just use your POJO, make their own POJO and everyone will get on with their lives drinking beer happily on the weekend.

Back to my massive refactor, in the end I kept getters and setters, I don't think the Java world is ready for the heresy of public fields (wink wink Python).