There was a child went forth every day,
And the first object he look'd upon, that object he became.
- Walt Whitman, There Was a Child Went Forth
Object orientation (OO) is the latest software methodology to occupy the airwaves, hyped to a point where the term "object-oriented design" seems to automatically imply a good design. In this chapter, we will study what the noise is all about and build objects using Perl. I will leave it to the plethora of OO literature to convince you that there is a respectable middle-ground and that the object revolution is indeed a good thing.
If you are already conversant with OO, you could simply read the "Objects" section in Appendix B, Syntax Summary. Among other things, it supplies a C++ example and translates it to equivalent Perl code.
Fred Brooks, in his classic The Mythical Man-Month , says:
The programmer at wit's end for lack of space can often do best by disentangling himself from his code, rearing back, and contemplating his data. Representation is the essence of programming.
He was talking about space reduction, but it is nevertheless sage advice.
Complex systems are inherently hierarchical, and many abstractions and methodologies have been invented to take advantage of this aspect. Until the late seventies, functional decomposition (top-down design) held sway as the definitive method to understand and implement complex systems. A developer would begin by writing high-level pseudo-code and continue refining each part of it until it was detailed enough to be translated into an implementation language. Nicklaus Wirth called this approach stepwise refinement. Then came structured methodologies, SA/SD (structured analysis/structured design) chief among them, which employed many tools and notations such as data-flow diagrams, process specifications, data dictionaries, state transition diagrams, and entity-relationship diagrams to design, document, and develop a system. The accent continued to be on the procedural side of systems development rather than on the dynamic (state transitions) or structural (data) facets.
The key realization in the last 15 years or so has been that a system's functionality tends to change a lot more than the data on which it acts. A personnel information system keeping track of employee details soon knows as much about an employee as it ever will. On the other hand, its functionality tends to track management reshuffles, tax laws, medical insurance changes, and the noisy arrivals and silent departures of Directors of Human Resources.
This realization has completely inverted the way a problem is tackled now. Data and ways of structuring it are now given primary importance, and code is organized in modules around important pieces of data. The benefits are immense and immediate.
First, the database and the code are in sync, since the code is organized along lines of data. There are those who cry about the "impedance mismatch" between object-oriented programs and relational databases (RDBMSs), but that is because RDBMSs have been limited to simple data types; there is no fundamental mismatch between the relational and object models. Vendors such as Informix/Illustra and Oracle have recently begun to offer abstract data types also in their RDBMS offerings.
Focusing on data has another important advantage: Data structures tend to be something you can identify with. For example, an airline company has airplanes, routes, and flight legs as prominent entities. In designing a flight-planning system, these entities provide a good focus on which to center your discussions, analysis, and design. Anybody who has had writer's block when starting a brand-new design document would surely appreciate this approach! The final design and implementation are also more comprehensible (and hence maintainable) because it is easier to explain. Fred Brooks remarks in The Mythical Man-Month, "Show me your flowcharts and conceal your tables, and I'll continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious."
Finally, a system divided into data-centric modules can be easily apportioned among a team of programmers. All changes to a given piece of data or a set of related data are done only by its "owner"; that developer becomes a component supplier for other people in the project.
Object orientation is the latest step along this course. Not only is the code data-centric, it also strives to encapsulate (hide) the actual data structures, preferring instead to expose a limited, well-documented interface: a set of functions that know how to manipulate these data structures. These data structures are called objects. VCRs, watches, cars, and other real-world objects are excellent examples of the kind of objects we wish to emulate, because they successfully hide all the myriad complexities behind really simple interfaces. (Of course, the fact that most VCRs show a blinking "12:00" indicates that there is still a considerable amount of interface simplification to be done.) While you can surely implement well-encapsulated data-centric designs using conventional languages such as C or COBOL or even assembler, object-oriented languages provide two features that are more than just syntactic conveniences: polymorphism and inheritance. We will see how these features facilitate the construction of reusable modules.
It must be stressed that OO methodologies are similar to SA/SD in that both account for the functional, dynamic, and structural aspects of a system. But they differ significantly in style and emphasis; OO design methodologies pay attention to data abstractions first and procedural abstractions last.