Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Architecture: Best practices for manipulating models without polluting the POJOs? And without repeating boiler-plate code everywhere [closed]

This is a problem we encounter often. There must be some best practices to address this...

Simplified Question

Where's the best place to put common code that manipulates POJOs?

such that:

  • POJOs only have properties and getters/setters
  • the same model manipulation code isn't repeated "everywhere"
  • it's very clear which classes are responsible for manipulating the model

Background

We have a schema that defines our domain. From that, we generate a "pure" model that consists of simple objects (POJOs) that come from JAXB.

In working with this model, several developers on the team have created boiler-plate code to access and manipulate the model. It is "sprinkled" in many places. Some have created wrapper objects that subclass instances of the model and add functionality. Others have created external utility classes. I'm looking to unify this code so that it's no longer "sprinkled everywhere." Ideally, the logic can be contained in a certain class of objects who are clearly responsible for generic manipulations of the model.

Example

Let's use a grocery store as a generic example. Model objects consist of things like:
Products, Aisle, Shelf, Employee, WorkSchedule, Vendor

Common model manipulations consist of things like:
findManagerWorkingOnDay(day, schedule), findAisleForProduct(apples), countItemsOnShelf(topShelf), product.isModified(), removeProductFromVendor(apples, vendor)

We don't want to "pollute" our Vendor POJO with a function like removeProductFromVendor. Likewise, we don't necessarily want to extend every model object, just to add the isModified property just so our GUI can know to "enable/disable" the save button.

Or do we?

Summary

Once a model object is in memory, who should be responsible for manipulating it--for instance, to iterate over a list of "employees on duty today" and find one who is a "manager?"

In these cases, database calls are overkill because we already have everything we need in memory (for ex: we've already queried the DataStore and we need to work with the result objects throughout the application). Ideally, this code would be available to any object who had, for example, a list of employees.


In terms of best practice, where is the ideal place to put the static method:
public static Employee findManager(List<Employee> employeesOnDuty);

which would iterate over the list of employees (POJOs) and return the first one where employee.title.toLowerCase().contains("manager")

If a team were to work with this sample object model, several people would write functions like this. What are some of the best practices to capture this responsibility such that POJOs remain "pure" and the same boiler-plate code isn't "sprinkled everywhere."

like image 404
gMale Avatar asked Jan 23 '12 15:01

gMale


1 Answers

Given that your POJO objects are from a vendor, I understand your reluctance to add functionality to them, and you obviously don't want code randomly sprinkled around your project.

Sounds like a job for either a set of Decorator subclasses, or as Ken suggests, facades.

I like decorators here because you'd then just refer to your vendor pojo by the name of the decorator class, which would then have the added behavior (isModified, searchByName, etc), all in one place.

like image 109
CPerkins Avatar answered Nov 11 '22 13:11

CPerkins