My original question was quite incorrect, I have classes (not POJO), which have shortcut methods for business logic classes, to give the consumer of my API the ability to use it like:
Connector connector = new ConnectorImpl();
Entity entity = new Entity(connector);
entity.createProperty("propertyName", propertyValue);
entity.close;
Instead of:
Connector connector = new ConnectorImpl();
Entity entity = new Entity();
connector.createEntityProperty(entity, "propertyName", propertyValue);
connector.closeEntity(entity);
Is it good practice to create such shortcut methods?
Old question
At the moment I am developing a small framework and have a pretty nice separation of the business logic in different classes (connectors, authentication tokens, etc.), but one thing is still bothers me. I have methods which manipulates with POJOs, like this:
public class BuisnessLogicImpl implements BusinessLogic{
public void closeEntity(Entity entity) {
// Business Logic
}
}
And POJO entities which also have a close method:
public class Entity {
public void close(){
businessLogic.closeEntity(this);
}
}
Is it good practice to provide two ways to do the same thing? Or better, just remove all "proxy" methods from POJOs for clarity sake?
You should remove the methods from the “POJOs”… They aren’t really POJO’s if you encapsulate functionality like this. The reason for this comes from SOA design principles which basically says you want loose coupling between the different layers of your application.
If you are familiar with Inversion of control containers, like Google_Guice or Spring Framework— this separation is a requirement. For instance, let’s say you have a
CreditCardPOJO and aCreditCardProcessorservice, and aDebugCreditCardProcessservice that doesn’t actually charge the CC money (for testing).In my example, I am relying on an IoC container to provide me with a
CardProcessor. Whether this is the debug one, or the real one… I don’t really care and neither does theCreditCardobject. The one that is provided is decided by your application configuration.If you had coupling between the processor and credit card where I could say
card.process(), you would always have to pass in theprocessorin the card constructor.CreditCardscan be used for other things besides processing however. Perhaps you just want to load aCreditCardfrom the database and get the expiration date… It shouldn’t need a processor to do this simple operation.You may argue: “The credit card could get the processor from a static factory”. While true, singletons are widely regarded as an anti-pattern requiring keeping a global state in your application.
Keeping your business logic separate from your data model is always a good thing to do to reduce the coupling required. Loose coupling makes testing easier, and it makes your code easier to read.