A lot of so-called Object-Oriented Programming is in fact nothing more than procedural code wrapped in objects. The funny thing is: many people actually defend this style of programming! This is one of the chief arguments:
“Objects should just be bags of state and nothing more. An invoice does not pay itself. An appointment does not reschedule itself. invoice.pay(anAmount)
and appointment.reschedule(aDate)
do not match the real world. Something on the outside drives the action. A service of some kind should do the paying and the rescheduling, and then update the state of those objects: invoice.setPaidAmount(anAmount)
and appointment.setDate(aDate)
. By consequence, not in the objects, but the services should contain the business logic.”
(Update: For the record, I do not agree with the view stated above in italics. What follows explains why encapsulating operations in objects, such as invoice.pay(…), is in fact the correct way to model objects.)
Of course invoices do not pay themselves, but that’s not what an object model is trying to do. An invoice exposes the behaviour of being able to be paid. That ability is in fact essential to what it means to be an invoice. The behaviour is an inherent property of an invoice. If an invoice doesn’t have the ability of being paid, there’s no point in issuing invoices at all. In other words, the contract of an invoice object declares that its interface includes payment as a feature. Its promise to the outside world is that it allows an outsider to pay for it.
Encapsulation of state and behaviour is the core idea behind objects. Go forth and encapsulate!
Language
Is the paradigm of Object-Oriented to blame for this widespread misunderstanding, or is it merely a matter of education? Part of the confusion is caused by the language. In languages like English, in an imperative sentence, the verb comes before the object. In OOP languages, it’s the other way around. I’d love to see a programming language that puts method calls before the object, but leaves the method arguments at the end : pay.invoice(anAmount)
and reschedule.appointment(aDate)
.