At this stage of the discussion, the reader is must be very much aware of the value, for both design and debugging purposes, of breaking large software projects down into constituent parts. Procedures are one such constituent, or piece of reusable software, and modules are another. Procedures are activity or flow-centred constituents; they deal with actions that either change data or alter the user perception or experience of the data. Modules are usually collections of such procedural activities, but may sometimes be centred around a particular data type and its appropriate manipulations. In the latter case, the term Abstract Data Type is appropriate to describe the entire collection (with its associated procedures) encapsulated in the module, and thinking in terms of such ADTs is a somewhat more data-centred approach to software design and implementation.
However, such ADTs are still rather activity-centric, for they offer collections of procedures, each of which can be passed a data entity of the appropriate type. A more data-centric approach than even the module ADT involves subordinating the manipulative activities and attributes to each individual data item, rather than to the type as a whole. Notationally, this is usually reflected by writing:
for a procedural or activity-centric approach:
Manipulate (a); c := SomeAttributeOf (a); Combine (a, b);
but, for a data-centric approach:
a.Manipulate; c := a.SomeAttribute; a.Combine (b);
To make things more concrete, consider an abstract data entity BankAccount with associated procedures Create, Destroy, Balance; Credit and Debit. In the conventional and action-oriented approach used so far in this text, one would write a module called Accounts containing, say, a type Account and the two procedures. A client program would declare the entity BankAccount to be of type Account and then issue invocations such as:
Create (BankAccount); Credit (BankAccount, 23.45); Debit (BankAccount, mortgage);
or, possibly, if the ADT were imported qualified,
Accounts.Debit (BankAccount, orthodonticsPayment); Current := Accounts.Balance (BankAccount);
For each of the procedure invocations, an account name has to be provided in the client code in order for the action to be valid.
In the object oriented approach, BankAccount would be the name of an object that would have its own access to the specified procedures and information (in this case, the balance) and the code of the procedures would be invoked by sending a message to the object to act as an agent in performing the required task, thus:
BankAccount.Credit (23.45); BankAccount.Debit (mortgage); Current := BankAccount.Balance;
The action of Credit does not stand alone waiting, as it were, to be given an account on which to act. Rather, it is owned by the account, which "knows" how to credit itself. That is, both attributes or qualities on the one hand, and activities or manipulative procedures on the other are tied to the data item itself, rather than being independent entities in their own right.
An astute reader ought to see some similarities between objects and modules and be able to take some things for granted here.
However, some other things are implicit in the data-centricity of this approach: