Perl Best Practices
The ham and cheese omelet class is worth special attention because it must inherit characteristics from the pork, dairy, and poultry classes. Thus, we see that the problem cannot be properly solved without multiple inheritance. At run time, the program must create the proper object and send a message to the object that says, "Cook yourself". The semantics of this message depend, of course, on the kind of object, so they have a different meaning to a piece of toast than to scrambled eggs. Reviewing the process so far, we see that the analysis phase has revealed that the primary requirement is to cook any kind of breakfast food. In the design phase, we have discovered some derived requirements. Specifically, we need an object- oriented language with multiple inheritance. Of course, users don't want the eggs to get cold while the bacon is frying, so concurrent processing is required, too. Do-While Jones The Breakfast Food Cooker The disadvantages of implementing classes via blessed hashes become even more pronounced when those classes are used as the bases of inheritance hierarchies. For example, the lack of encapsulation makes it almost inevitable that base-class attributes will be accessed directly in derived-class methods, thereby strongly coupling the two classes. This notion that derived classes should have some kind of exemption to the encapsulation of their base classusually known as "protected access"certainly seemed like a good idea at the time. But long and bitter experience now strongly suggests that this practice is just as detrimental to the maintainability of class hierarchies as full "public access" is. Worse still, in a hash-based object, the attributes live in a single namespace (the keys of the hash), so derived classes have to contend with their base classes, and with each other, for ownership of particular attributes. Other serious problems can also arise in Perl class hierarchies, regardless of their underlying implementation type. Constructor and destructor methods have no privileged status, and constructors usually intermix the creation and initialization of objects. These two factors make it easy for subclassesespecially those inheriting from multiple base classesto misconstruct, incompletely initialize, or only partially clean up their derived objects. This chapter describes a set of design and coding practices that avoid all these problems. |