| This trivial example does not illustrate the usefulness of OO design. Extending the example imagine the requirement is that the target of an email may be either a single user or a group of users, and in addition, email filters can be configured for both individual users and groups of users Leading to an OO class design roughly like this:
(there are other possible OO designs, but this illustrates the point) // Send an email to a specific user or a group of user taking into account both user and group level filters. sendEmail(Email, EmailDestination) class Email {Title, Body, Attachments} interface EmailDestination { Iterator<User> getRecipients(Email);
List<Filter> getFilters();
}class Group implements EmailDestination { // returns group filters
List<Filters> getFilters();
List<User> getMembers();
// returns all recipients after applying group and
// individual recipient filters
List<User> getRecipients(Email);
}class User implements EmailDestination { // returns user specific filters.
List<Filters> getFilters();
// returns itself unless filtered
Iterator<User> getRecipients(Email);
}how would this look with a procedural design? |
A bit off topic but note that... anExampleFilterFunction can be implemented to filter off of a User and a group at the same time or it can filter off of the email address itself. I could also compose filterByAFunction with itself in an innumerable amount of ways to produce any amount of custom filters:
The tricks(s) above cannot be done if I had everything encapsulated in objects. Objects are not compose-able. You cannot combine User or Group to create a UserAndGroup filter without explicitly defining a whole new class. Also in the end all a program really is doing is calling functions. Classes are just layers of cruft that have no meaning during execution.